BT编程语言文档
Regex正则表达式
Regex:是正则表达式(regular expression)的简写。 正则表达式(Regular Expression)是一种强大的文本处理工具,用于匹配字符串中的特定模式。它由普通字符和特殊字符(称为元字符)组成,用于描述一种字符串匹配的模式。正则表达式可以检查一个字符串是否含有某种子串、将匹配的子串做替换或从某个字符串中取出符合某个条件的子串等。 正则表达式在许多编程语言和文本编辑器中都有广泛应用,例如VsCode、SublimeText等工具,以及PHP、Perl、Java、JavaScript、C#等编程语言。它主要用于文本搜索、替换、模式匹配等操作,能够帮助程序员高效地处理和分析文本数据。 例如:一个简单的正则表达式^\d+$
用于匹配一串数字,其中^
表示字符串的开始,\d+
表示一个或多个数字。
语法
正则表达式主要由两个斜杠组成,最后一个斜杠后面为修饰符,用于配置匹配模式,如下:re = /pattern/modifiers
pattern(模式) 表达式的模式 modifiers(修饰符) 用于指定全局匹配、区分大小写的匹配和多行匹配 // 声明一个正则类型,用于匹配四位数,全局匹配 re = /\d{4}/g修饰符
修饰符用于执行区分大小写和全局匹配:-
i
执行对大小写不敏感的匹配 -
g
执行全局匹配(查找所有匹配而非在找到第一个匹配后停止) -
m
执行多行匹配 -
s
允许 . 匹配 \n
字符类
字符类允许你定义匹配一组字符的规则,支持以下几种模式:-
[xyz]
匹配 x、y 或 z 中的任意一个字符(并集) -
[^xyz]
匹配除 x、y 和 z 之外的任何字符(取反) -
[0-9]
匹配 0 到 9 范围内的数字(区间匹配) -
[a-z]
匹配 a 到 z 范围内的任何小写字母(区间匹配) -
[A-Z]
匹配 A 到 Z 范围内的任何大写字母(区间匹配) -
[A-z]
匹配 A 到 z 范围内的任何大写和小写字母(区间匹配) -
[[:alpha:]]
匹配任意字母字符(ASCII 字符类,等价于 [A-Za-z]) -
[[:^alpha:]]
匹配任何非字母字符(取反的 ASCII 字符类,等价于 [^A-Za-z]) -
[x[^xyz]]
嵌套/分组字符类,匹配 x 和除 y 和 z 之外的任意字符 -
[a-y&&xyz]
交集操作,匹配 x 或 y(即 a-y 与 xyz 的交集) -
[0-9&&[^4]]
使用交集和取反进行的减法操作,匹配 0-9 中除 4 之外的字符 -
[0-9--4]
直接减法操作,匹配 0-9 中除 4 之外的字符 -
[a-g~~b-h]
对称差操作,匹配 a 和 h(即 a-g 与 b-h 的对称差) -
[\[\]]
在字符类中转义,匹配 [ 或 ] -
[a&&b]
空字符类,匹配不到任何字符
元字符
元字符(Metacharacter)是拥有特殊含义的字符:-
.
匹配任意字符,除了换行符(如果设置了 s 标志,. 也可以匹配换行符) -
\d
匹配任意数字字符(等价于 Unicode 类 \p{Nd}) -
\D
匹配任意非数字字符 -
\s
匹配任意空白字符(包括空格、制表符等) -
\S
匹配任意非空白字符 -
\w
匹配任意单词字符(包括字母、数字和下划线) -
\W
匹配任意非单词字符 -
\*
匹配字面上的 *,适用于所有 ASCII 字符,除了 [0-9A-Za-z<>] -
\a
响铃符(\x07) -
\f
换页符(\x0C) -
\t
水平制表符(tab 键) -
\n
换行符 -
\r
回车符 -
\v
垂直制表符(\x0B) -
\A
匹配输入的开头 -
\z
匹配输入的结尾 -
\b
单词边界断言 -
\B
非单词边界断言(即反向的单词边界) -
\b{start}, \<
单词开始边界断言 -
\b{end}, \>
单词结束边界断言 -
\b{start-half}
单词开始边界的半边断言 -
\b{end-half}
单词结束边界的半边断言 -
\123
八进制字符代码,最多三位数(当启用时) -
\x7F
十六进制字符代码(精确为两位) -
\x{10FFFF}
任何对应于 Unicode 代码点的十六进制字符代码 -
\u007F
十六进制字符代码(精确为四位) -
\u{7F}
任何对应于 Unicode 代码点的十六进制字符代码 -
\U0000007F
十六进制字符代码(精确为八位) -
\U{7F}
任何对应于 Unicode 代码点的十六进制字符代码 -
\p{Letter}
Unicode 字符类(例如,匹配任意字母字符) -
\P{Letter}
反向的 Unicode 字符类(例如,匹配任何非字母字符) -
\pX
匹配由一个字母标识的 Unicode 字符类,例如 \pL 匹配所有字母 -
\PX
匹配由一个字母标识的取反 Unicode 字符类,例如 \PL 匹配非字母字符
重复匹配
在BT的正则表达式中,可以使用以下语法来指定重复模式:-
x*
匹配零次或多次 x(贪婪匹配) -
x+
匹配一次或多次 x(贪婪匹配) -
x?
匹配零次或一次 x(贪婪匹配) -
x*?
匹配零次或多次 x(非贪婪/懒惰匹配) -
x+?
匹配一次或多次 x(非贪婪/懒惰匹配) -
x??
匹配零次或一次 x(非贪婪/懒惰匹配) -
x{n,m}
匹配至少 n 次 x,且至多 m 次 x(贪婪匹配) -
x{n,}
匹配至少 n 次 x(贪婪匹配) -
x{n}
精确匹配 n 次 x -
x{n,m}?
匹配至少 n 次 x,且至多 m 次 x(非贪婪/懒惰匹配) -
x{n,}?
匹配至少 n 次 x(非贪婪/懒惰匹配) -
x{n}?
精确匹配 n 次 x(非贪婪/懒惰匹配)
提示:在这里,贪婪匹配 意味着正则表达式会尽可能多地匹配,而 非贪婪/懒惰匹配 则会尽可能少地匹配
空匹配
以下是BT正则表达式中与空匹配相关的符号及其含义:-
^
匹配输入的开头(或在多行模式下匹配行的开头) -
$
匹配输入的结尾(或在多行模式下匹配行的结尾) -
\A
仅匹配输入的开头(即使启用了多行模式也只匹配整个文本的开头) -
\z
仅匹配输入的结尾(即使启用了多行模式也只匹配整个文本的结尾) -
\b
匹配 Unicode 单词边界(当一侧是单词字符 \w,另一侧是非单词字符 \W、\A 或 \z 时) -
\B
匹配非 Unicode 单词边界 -
\b{start}, \<
匹配 Unicode 单词开头边界(左侧为 \W 或 \A,右侧为 \w) -
\b{end}, \>
匹配 Unicode 单词结尾边界(左侧为 \w,右侧为 \W 或 \z) -
\b{start-half}
匹配半个 Unicode 单词开头边界(左侧为 \W 或 \A) -
\b{end-half}
匹配半个 Unicode 单词结尾边界(右侧为 \W 或 \z)
提示:这些符号常用于匹配位置或边界,而不是实际字符
分组与标志
在BT正则表达式中,可以使用以下语法来进行分组:-
(exp)
编号捕获组,捕获的内容会根据左括号的顺序进行编号(从 1 开始)。 -
(?P
或exp) (?
命名捕获组,同时也会被编号。组名必须是字母数字(a-z, A-Z, 0-9)。exp) -
(?:exp)
非捕获组,这种组只进行匹配但不会捕获结果。 -
(?flags)
在当前分组中设置标志(影响该分组内的匹配方式)。 -
(?flags:exp)
为特定的表达式 exp 设置标志,且该表达式为非捕获组。
ASCII 字符类
以下是基于 UTS#18 提供定义的 ASCII 字符类及其含义:-
[[:alnum:]]
字母数字字符(即 [0-9A-Za-z])。 -
[[:alpha:]]
字母字符(即 [A-Za-z])。 -
[[:ascii:]]
ASCII 字符(即 [\x00-\x7F],包括从 0 到 127 的所有 ASCII 字符)。 -
[[:blank:]]
空白字符(即 [\t ],包括水平制表符和空格)。 -
[[:cntrl:]]
控制字符(即 [\x00-\x1F\x7F],包括不可打印的控制字符)。 -
[[:digit:]]
数字字符(即 [0-9])。 -
[[:graph:]]
可见的图形字符(即 [!-~],包括除空格外的所有可打印字符)。 -
[[:lower:]]
小写字母(即 [a-z])。 -
[[:print:]]
可打印字符(即 [ -~],包括空格和所有可见的图形字符)。 -
[[:punct:]]
标点符号(即 [!-/:-@\[-{-~]`,包括标点和符号)。 -
[[:space:]]
空白字符(即 [\t\n\v\f\r ],包括制表符、换行符、垂直制表符、换页符、回车符和空格)。 -
[[:upper:]]
大写字母(即 [A-Z])。 -
[[:word:]]
单词字符(即 [0-9A-Za-z_],包括字母、数字和下划线)。
Unicode支持
Unicode 对内存使用和搜索速度的影响
该正则表达式库默认启用了对 Unicode 的全面支持,在大多数情况下,支持Unicode所需的额外内存开销是可以忽略的,并且通常不会影响搜索速度,但在某些情况下可能会有影响。关于内存使用:
Unicode 的影响主要体现在 Unicode 字符类的使用上。Unicode 字符类往往非常庞大。例如,默认的 \w 匹配大约 14 万个不同的代码点。这需要额外的内存,并可能使正则表达式的编译变慢。虽然偶尔使用 \w 影响不大,但如果你写了 \w{100},那么默认情况下将生成一个相当大的正则表达式。 例如,(?-u:\w) 的 ASCII 版本明显比 Unicode 版本小得多,所以如果你的需求可以通过 ASCII 满足,最好使用 ASCII 字符类。ASCII 版本的 \w 可以通过多种方式表示,以下都是等价的:-
[0-9A-Za-z_]
-
(?-u:\w)
-
[[:word:]]
-
[\w&&\p{ascii}]
关于搜索速度:
即使使用大型 Unicode 字符类,搜索速度通常也能很好地处理 Unicode。不过,一些更快的内部正则表达式引擎无法处理支持 Unicode 的单词边界断言。因此,如果你不需要 Unicode 感知的单词边界断言,建议使用(?-u:\b)
代替 \b
,前者使用 ASCII 版本的单词字符定义。
总之,虽然启用 Unicode 支持通常不会显著影响内存和性能,但在某些情况下使用 ASCII 类可以减少开销并提升性能。
BT语言的正则完全实现了 Unicode 技术标准 #18(UTS#18)中规定的“基本 Unicode 支持”(第一级)。
字符类 \w、\d 和 \s 默认都是支持 Unicode 的。使用 (?-u:\w)
(?-u:\d)
和 (?-u:\s)
可获得仅支持 ASCII 的定义。
类似的 \b 和 \B 使用 Unicode 定义的“单词”字符。若要获得仅支持 ASCII 的单词边界,可使用(?-u:\b)
和(?-u:\B)
。这同样适用于特殊的单词边界断言(即 \b{start}
、\b{end}
、\b{start-half}
、\b{end-half}
)。
在多行模式下,^ 和 $ 不支持 Unicode,也就是说,它们只识别 \n(假设未启用 CRLF 模式),而不会识别 Unicode 定义的其他行终止符形式。
大小写不敏感的搜索支持 Unicode 并使用简单的大小写折叠。
Unicode 的一般类别、脚本和许多布尔属性默认可通过 \p{property name}
语法使用。
在所有情况下,匹配的结果都使用字节偏移量报告,准确地说,是 UTF-8 编码单元的偏移量。这允许在常数时间内对文本进行索引和切片操作。
在BT中,默认情况下,正则匹配是 Unicode 感知的,这意味着它可能匹配的比你想象的要多。例如:\d
print "𝟚𝟘𝟙𝟘-𝟘𝟛-𝟙𝟜".match(/^\d{4}-\d{2}-\d{2}$/) // 输出 [𝟚𝟘𝟙𝟘-𝟘𝟛-𝟙𝟜]
要仅匹配 ASCII 十进制数字,以下所有内容都是等效的:
-
[0-9]
-
(?-u:\d)
-
[[:digit:]]
-
[\d&&\p{ascii}]