3. I-Regexp 语法
3. I-Regexp 语法
I-Regexp MUST 符合图 1 中的 ABNF 规范.
i-regexp = branch *( "|" branch )
branch = *piece
piece = atom [ quantifier ]
quantifier = ( "*" / "+" / "?" ) / range-quantifier
range-quantifier = "{" QuantExact [ "," [ QuantExact ] ] "}"
QuantExact = 1*%x30-39 ; '0'-'9'
atom = NormalChar / charClass / ( "(" i-regexp ")" )
NormalChar = ( %x00-27 / "," / "-" / %x2F-3E ; '/'-'>'
/ %x40-5A ; '@'-'Z'
/ %x5E-7A ; '^'-'z'
/ %x7E-D7FF ; skip surrogate code points
/ %xE000-10FFFF )
charClass = "." / SingleCharEsc / charClassEsc / charClassExpr
SingleCharEsc = "\" ( %x28-2B ; '('-'+'
/ "-" / "." / "?" / %x5B-5E ; '['-'^'
/ %s"n" / %s"r" / %s"t" / %x7B-7D ; '{'-'}'
)
charClassEsc = catEsc / complEsc
charClassExpr = "[" [ "^" ] ( "-" / CCE1 ) *CCE1 [ "-" ] "]"
CCE1 = ( CCchar [ "-" CCchar ] ) / charClassEsc
CCchar = ( %x00-2C / %x2E-5A ; '.'-'Z'
/ %x5E-D7FF ; skip surrogate code points
/ %xE000-10FFFF ) / SingleCharEsc
catEsc = %s"\p{" charProp "}"
complEsc = %s"\P{" charProp "}"
charProp = IsCategory
IsCategory = Letters / Marks / Numbers / Punctuation / Separators /
Symbols / Others
Letters = %s"L" [ ( %s"l" / %s"m" / %s"o" / %s"t" / %s"u" ) ]
Marks = %s"M" [ ( %s"c" / %s"e" / %s"n" ) ]
Numbers = %s"N" [ ( %s"d" / %s"l" / %s"o" ) ]
Punctuation = %s"P" [ ( %x63-66 ; 'c'-'f'
/ %s"i" / %s"o" / %s"s" ) ]
Separators = %s"Z" [ ( %s"l" / %s"p" / %s"s" ) ]
Symbols = %s"S" [ ( %s"c" / %s"k" / %s"m" / %s"o" ) ]
Others = %s"C" [ ( %s"c" / %s"f" / %s"n" / %s"o" ) ]
图 1: ABNF 表示的 I-Regexp 语法
作为额外限制, charClassExpr 不允许匹配 [^]; 根据此语法, 它会被解析为包含单个字符 ^ 的正字符类.
这本质上是去除了以下功能的 XSD regexp:
- 字符类减法,
\s,\S,\w等多字符转义, 以及- Unicode 块.
I-Regexp 实现 MUST 完整实现这个受限子集. 特别是, REQUIRED 完全支持本规范中定义的 Unicode 功能. 实现:
- MUST NOT 将自身限制为 ASCII 等 7 位或 8 位字符集, 并且
- MUST 支持字符类中的 Unicode 字符属性集.
3.1 检查型实现
检查型 I-Regexp 实现会检查提供的 regexp 是否符合本规范, 并报告任何问题. 检查型实现可让用户确信自己没有意外插入不可互操作的语法, 因此 RECOMMENDED 执行检查. 对于低投入实现, 可以对此规则作例外处理; 这类实现通过简单步骤将 I-Regexp 映射到另一个 regexp 库, 例如执行第 5 节讨论的映射操作. 在这种情况下, 完整检查所需的工作量可能远超实现其余部分的工作量. 实现 SHOULD 记录自己是否执行检查.
采用 I-Regexp 的规范可能需要定义: 其实现在哪些情况下可以使用非检查型 I-Regexp 实现, 以及何时需要完整检查; 这也可能发生在定义自身实现类别的过程中.