Learning boost sp 2
regex语法规范(翻译)
这部分包含了boost.regex库的正则表达式的语法。这是一份程序员指南,实际的语法由在程序中的正则表达式的选项决定。(译注:即regex类构造函数的flag参数。)
文字(Literals)
除了一下字符,其它的任何字符都表示其字面意义(literal)。
“.”, “|”, “*”, “?”, “+”, “(“, “)”, “{“, “}”, “[“, “]”, “^”, “$” 和 “/”
要使用这些字符的字面意义,要在前面使用 “/” 字符。一个字面意义的字符匹配其本身,或者匹配 traits_type::translate() 的结果,这里的traits_type 是 basic_regex 类的特性模板参数(the traits template parameter)。
通配符(Wildcard)
点号 ”.” 匹配任意的单个字符。当在匹配算法中使用了 match_not_dot_null 选项,那么点号不匹配空字符(null character)。当在匹配算法中使用了 match_not_dot_newline 选项,那么点号不匹配换行字符(newline character)。
重复(Repeats)
一个重复是一个表达式(译注:正则表达式)重复任意次数。一个表达式后接一个 “*” 表示重复任意次数(包括0次)。一个表达式后接一个 “+” 表示重复任意次数(但是至少1次)。如果表达式使用 regex_constants::bk_plus_qm编译(译注:regex类构造函数的flag参数),那么 “+” 是一个普通的字符(译注:即 “+” 表示其字面意义), “/+” 用来表示重复一或多次。一个表达式后接一个 “?” 表示重复0或1次。如果表达式使用 regex_constants::bk_plus_qm 选项,那么 “?” 是一个普通字符,”/?” 用来表示重复0或1次。如果需要显式的指定重复的最大最小次数的话,请使用边界操作符 “{}”,那么 “a{2}” 表示字母 “a” 重复2次, “a{2,4}” 表示字母 “a” 重复2至4次, “a{2,}” 表示字母 “a” 重复至少2次(无上限)。注意:在{}之间是没有任何空格的,并且上下边界的大小是没有上限的。如果表达式使用 regex_constants::bk_braces 选项编译,那么 “{” 和 “}” 是普通字符, “/{” 和 “/}” 用来表示边界操作符。所有的重复表达式是最短的前置子串(the shortest possible previous sub-expression):单个字符,字符集合,或者是用诸如 “()” 括起来的子表达式。
例:
“ba*” 匹配 “b”, “ba”, “baaa” 等等。
“ba+” 匹配诸如 “ba”, “baaaa” 此类,而不匹配 “b”。
“ba?” 匹配 “b” 或 “ba”。
“ba{2,4}” 匹配 “baa”, “baaa” 和 “baaaa”。
非“贪心”重复(Non-greedy repeats)
无论是否启用“扩展(extended)”正则表达式语法(默认的),总是允许使用非贪心重复,只要在重复的后面加一个 “?” 。非贪心重复是匹配最短可能串(the shortest possible string)的重复。
例如要匹配html的一对标签,可以使用:
“</s*tagname[^>]*>(.*?)</s*/tagname/s*>”
这里$1会包含标签之间的文本,这段文本是最短匹配的字符串。
圆括号(Parenthesis)
圆括号有两个作用:组成子表达式和标记匹配(to group items together into a sub-expression, and to mark what generated the match.)。例如,表达式 “(ab)*” 匹配所有的 “ababab”字符串。匹配算法 regex_match 和 regex_search 各需要一个match_results对象来报告是怎样匹配的,函数返回后match_results会包含整个表达式和各个子表达式的匹配。比如在上述的例子中,match_results[1]会包含表示最后一个 “ab” 的迭代器对(pair)。子表达式也允许匹配空串。如果子表达式匹配为空 - 例如子表达式为选择中的不匹配的那一部分 – 那么一对迭代器指向输入字符串的结尾,并且这个子表达式的matched属性为false。子表达式从左向右,从1开始索引,子表达式0是整个表达式。(译注:上述表达式或子表达式都是指正则表达式。)
非标记圆括号(Non-Marking Parenthesis)
有时你需要使用圆括号组成一个子表达式,但是不像要产生一个标记的子表达式(译注:在match_results中的表达式都是标记的子表达式)。在这种情况下,非标记圆括号 (?:expression) 可以使用。例如下列表达式不产生子表达式:
“(?:abc)*”
前看断言(Forward Lookahead Asserts )
这有两种形式:一个是正的前看断言;一个是负的前看断言:
“(?=abc)” 匹配0个字符,除非表达式以 “abc” 开头。
“(?!abc)” 匹配0个字符,除非表达式不以 “abc” 开头。
(译注:断言并不匹配,例如: “(?=abc)abcdef” 匹配 “abcdef” ,前面的 “(?=abc)” 并不匹配 “abc” ,而是查看是否已abc开头,如果需要匹配 “abc” 还是需要在后面写上的。)
独立子表达式(Independent sub-expressions)
“(?>expression)” 匹配 “expression” 作为一个独立的原子动作(除非产生错误,算法不会回退产看)。
选择(Alternatives)
选择出现在需要匹配一个子表达式或另一个子表达式的情况下。每个选择的项目使用 “|” 分割,或者当设置了 regex_constants::bk_vbar 选项的时候,使用 “/|” 分割,或者当设置了 regex_constants::newline_alt 选项的时候,使用换行符分割。每个选择的项目总是最长可能的子表达式,这和重复操作符的情况相反。
例:
“a(b|c)” 匹配 “ab” 或 “ac”。
“abc|def” 匹配 “abc” 或 “def”。
集合(Sets)
集合是一个字符的集合,它能够匹配任意是其成员的字符。集合使用 “[” 和 “]” 来包含文字,字符范围,字符类,对照元素和等值类。使用 “^” 开头的集合表示补集。
例:
字符文字:
"[abc]" 匹配 "a", "b", 或 "c"。
"[^abc] 匹配除 "a", "b", 和 "c" 之外的任何字符。
字符范围:
"[a-z]" 匹配任意在 "a" 至 "z" 之间的字符。
"[^A-Z]" 匹配在 "A" 至 "Z" 之外的字符。
注意,如果设置 regex_constants::collate 选项,那么字符范围的依赖于地域的(locale dependent):它们匹配任意在范围两端之间的字符,当使用默认的 “C” locale 的时候,范围遵循ASCII的规则。例如,如果库是使用Win32地域模型编译的话,那么 [a-z] 会匹配 a-z的ASCII字符和 ‘A’, ’B’ 等,但不匹配 ‘Z’ ,它正好在’z’的后面。默认情况下,地域特殊化的行为的禁止的,范围的比较遵循ASCII字符的编码。
字符类是使用 “[:classname:]” 语法声明的集合。例如 “[[:space:]]” 是所有空白字符的集合。只有当设置了 regex_constants::char_classes 选项后,字符类才有效。可用的字符类有:
alnum | 任何字符数字 |
alpha | a-z和A-Z之间的字母。如果设置了地域的话,可能包含其它字符。 |
blank | 任何空白字符,空格或者tab字符。 |
cntrl | 任何控制字符 |
digit | 任何0-9之间的数字 |
graph | 任何图形字符 |
lower | a-z之间的小写字符。如果设置了地域的话,可能包含其它字符。 |
| 任何可打印字符 |
punct | 任何标点符号 |
space | 任何空格字符 |
upper | A-Z之间的大写字母。如果设置了地域的话,可能包含其它字符。 |
xdigit | 任何在0-9,a-f和A-F之间的16进制数字 |
word | 任何单词字符 – 字母数字加上下划线 |
Unicode | 任何编码大于255的字符,只能在宽字符中使用 |
当设置了 regex_constants::escape_in_lists 选项后,你可以使用一些字符类的缩写:
/w 代替 [:word:]
/s代替 [:space:]
/d代替[:digit:]
/l代替[:lower:]
/u代替[:upper:]
对照元素(Collating elements)是集合声明中的通过 [.tagname.] 表示,此处 tagname 是单个字符或者是对照元素的名称。例如 [[.a.]] 相当于 [a] ,[[.comma.]] 相当于 [,] 。库支持所有标准POSIX的对照元素名称和下列额外的名称: “ae”, “ch”, “ll”, “ss”, “nj”, “dz”, “lj” ,每个都可以小写,大写或开头大写。多字符对照元素令集合匹配一个以上的字符,例如 [[.ae.]]匹配两个字符,而 [^[.ae.]]只匹配一个字符。
Equivalence classes take the generalform[=tagname=] inside a set declaration, where tagname is either a single character, or a name of a collating element, and matches any character that is a member of the same primary equivalence class as the collating element [.tagname.]. An equivalence class is a set of characters that collate the same, a primary equivalence class is a set of characters whose primary sort key are all the same (for example strings are typically collated by character, then by accent, and then by case; the primary sort key then relates to the character, the secondary to the accentation, and the tertiary to the case). If there is no equivalence class corresponding to tagname ,then[=tagname=] is exactly the same as [.tagname.]. Unfortunately there is no locale independent method of obtaining the primary sort key for a character, except under Win32. For other operating systems the library will "guess" the primary sort key from the full sort key (obtained from strxfrm), so equivalence classes are probably best considered broken under any operating system other than Win32.
To include a literal "-" in a set declaration then: make it the first character after the opening "[" or "[^", the endpoint of a range, a collating element, or if the flag regex_constants::escape_in_lists is set then precede with an escape character as in "[/-]". To include a literal "[" or "]" or "^" in a set then make them the endpoint of a range, a collating element, or precede with an escape character if the flag regex_constants::escape_in_lists is set.
行锚 (Line anchors )
锚(anchor)是用来在一行开头或结尾匹配空串的: “^” 在一行的开头匹配空串, “$” 匹配行尾的空串。
回退引用(Back references)
回退引用是对已经匹配的子表达式的引用,这个引用是子表达式匹配的字符串,而不是子表达式本身。回退引用由换码符 “/” 加一个 “1” 到 “9” 的数字组成, “/1” 引用第一个子表达式, “/2” 引用第二个 等等。 例如表达式 “(.*)/1” 匹配任何重复2次的字符串,比如 “abcabc” 或 “xyzxyz”。子表达式的回退引用不参与任何匹配,匹配空串:NB 这不同于其它一般性的正则式匹配。只有使用了 regex_constants:bk_refs 选项才能使用回退引用。
编码的字符(Characters by code )
这是算法的一个扩展,在其它的库中是没有的。它由换码符加数字 “0” 加 10进制的字符编码组成。例如 “/023” 表示10进制编码是23的字符。当使用圆括号分割了表达式时,可能引起模糊: “/0103” 表示103编码的字符, “(/010) 3” 表示字符10接着一个 “3”。要使用16进制编码的话,用 /x 加一个16进制数就可以了,可以使用 {} 括起来,例如 /xf0 或 /x{aff} ,注意后一个例子是一个Unicode字符。
单词操作符(Word operators )
下列操作符提供了与GNU正则式库德兼容。
“/w” 匹配任何属于 “word” 类的字符,相当于 “[[:word:]]”。
“/W” 匹配任何不属于 “word” 类的字符,相当于 “[^[:word:]]”。
“/<” 匹配一个单词开头的空串。
“/>” 匹配一个单词结尾的空串。
“/b” 匹配单词开头或结尾的空串。
“/B” 匹配单词内的空串。
The start of the sequence passed to the matching algorithms is considered to be a potential start of a word unless the flag match_not_bow is set. The end of the sequence passed to the matching algorithms is considered to be a potential end of a word unless the flag match_not_eow is set.
缓冲操作符(Buffer operators )
下列操作符提供了与GNU正则式库和Perl正则式库的兼容:
“/`” 匹配一个缓冲的开头(the start of a buffer)。
“/A” 匹配缓冲的开头(the start of the buffer)。
“/’” 匹配缓冲的结尾。
“/z” 匹配缓冲的结尾。
“/Z” 匹配缓冲的结尾,可能包含一或多个换行符。
一个缓冲是提供给匹配算法的整个序列,除非设置了 match_not_bob 或 match_not_eob 选项。
换码操作符(Escape operator)
换码字符 “/” 有好几个意思。
在集合声明内,换码符是一个普通的字符,除非设置了 regex_constants::escape_in_lists 选项,此时 “/” 之后的字符表示其字面意义而不考虑其原来的意思。
换码符可以引出其它的操作,例如:回退引用,或单词操作符。
换码符可以接一个正常的字符,例如 “/*” 表示一个字面意义的 “*” 而不是重复操作符。
单字符换码串(Single character escape sequences )
下列是单个字符的换码串:
换码串 | 字符编码 | 含义 |
/a | 0x07 | Bell character. |
/f | 0x 0C | Form feed. |
/n | 0x 0A | Newline character. |
/r | 0x0D | Carriage return. |
/t | 0x09 | Tab character. |
/v | 0x0B | Vertical tab. |
/e | 0x1B | ASCII Escape character. |
/0dd | 0dd | An octal character code, where dd is one or more octal digits. |
/xXX | 0xXX | A hexadecimal character code, where XX is one or more hexadecimal digits. |
/x{XX} | 0xXX | A hexadecimal character code, where XX is one or more hexadecimal digits, optionally a Unicode character. |
/cZ | z-@ | An ASCII escape sequence control-Z, where Z is any ASCII character greater than or equal to the character code for '@'. |
各种换码串:
下列提供了和perl的兼容,但注意 /1 /L /u和/U的不同之处:
/w 相当于 [[:word:]]。
/W 相当于 [^[:word:]]。
/s 相当于 [[:space:]]。
/S 相当于 [^[:space:]]。
/d 相当于 [[:digit:]]。
/D 相当于 [^[:digit:]]。
/l 相当于 [[:lower:]]。
/L 相当于 [^[:lower:]]。
/u 相当于 [[:upper:]]。
/U 相当于 [^[:upper:]]。
/C 任何字符,相当于'.'。
/X 匹配任何Unicode组和字符串,例如"a/x 0301" (带重音号的字符)。
/Q 开始引用操作符,任何后面的字符被认为是字面意义,除非是/E 结束引用操作符的出现。
/E 结束引用操作符,终止/Q开始的序列。
What gets matched?
When the expression is compiled as a Perl-compatible regex then the matching algorithms will perform a depth first search on the state machine and report the first match found.
When the expression is compiled as a POSIX-compatible regex then the matching algorithms will match the first possible matching string, if more than one string starting at a given location can match then it matches the longest possible string, unless the flag match_any is set, in which case the first match encountered is returned. Use of the match_any option can reduce the time taken to find the match - but is only useful if the user is less concerned about what matched - for example it would not be suitable for search and replace operations. In cases where their are multiple possible matches all starting at the same location, and all of the same length, then the match chosen is the one with the longest first sub-expression, if that is the same for two or more matches, then the second sub-expression will be examined and so on.
The following table examples illustrate the main differences between Perl and POSIX regular expression matching rules:
表达式 | 文本 | POSIX最左长匹配 | ECMAScript深度优先搜索匹配 |
a|ab | xaby | “ab” | “a” |
.*([[:alnum:]]+).* | " abc def xyz " | $0 = " abc def xyz " $1 = "abc" | $0 = " abc def xyz " $1 = "z" |
.*(a|xayy) | zzxayyzz | "zzxayy" | "zzxa" |
These differences between Perl matching rules, and POSIX matching rules, mean that these two regular expression syntaxes differ not only in the features offered, but also in the form that the state machine takes and/or the algorithms used to traverse the state machine.