我想我在.NET Regex引擎中发现了一个错误,并且想知道是否有其他人遇到过它,或者它是否有某种预期的行为。
在前导组<table width="600px" max-width="100%" align="center">
<tr><td>content......</td><td>content....</td></tr>
<tr><td>content......</td><td>content....</td></tr>
<tr><td>content......</td><td>content....</td></tr>
<tr><td>content......</td><td>content....</td></tr>
</table>
内的一组备选\Z
内匹配输入字符断言[]
的结尾时会发生这种情况,如此示例表达式中所示在创建时抛出异常。
(?=)
返回的例外是Regex test = new Regex(@"(?=[\Z])");
然而正则表达式,parsing "(?=[\Z])" - Unrecognized escape sequence \Z.
正常工作[\Z]
解决方法很简单,使用 (?=\Z)
和替代组中需要的其他任何替代字符,但它仍然很奇怪。
编辑:我认为我的原始测试中肯定存在拼写错误,因为正如nhahtdh指出的那样,上述模式实际上会抛出异常。
使用C#
在.NET 4.5中测试答案 0 :(得分:3)
我不知道为什么你声称@"[\Z]"
工作,但是从我对ideone(目前运行在.NET 4.0.30319.17020)上的测试中,它抛出与{{1}相同的异常}:
@"(?=[\Z])"
顺便说一下,System.ArgumentException: parsing '[\Z]' - Unrecognized escape sequence Z.
at System.Text.RegularExpressions.RegexParser.ScanCharEscape () [0x00000] in <filename unknown>:0
at System.Text.RegularExpressions.RegexParser.ScanCharClass (Boolean caseInsensitive, Boolean scanOnly) [0x00000] in <filename unknown>:0
[...]
也会抛出异常,因为它会尝试解析由(?=[]|\Z)
,]
组成的字符类,并遇到无效的转义序列|
。< / p>
检查RegexParser.ScanCharEscape
的代码,但ECMAScript模式(\Z
除外)如果代码遇到!UseOptionE()
,后面跟一个不知道的单词字符,代码会引发异常转义序列(请注意,在.NET中,单词字符不仅限于\
,还包括Unicode中的其他单词字符。)
A-Za-z0-9_
这可能是一个设计决定,允许将来扩展转义语法,而不会破坏现有的代码库,当人们转向更新版本的.NET框架时。 Java在 default:
if (!UseOptionE() && RegexCharClass.IsWordChar(ch))
throw MakeException(SR.Format(SR.UnrecognizedEscape, ch.ToString()));
return ch;
类中也遵循相同的设计原则,但它仅为Pattern
的无法识别的转义序列抛出异常。另一方面,JavaScript / ECMAScript没有这样的限制,它将无法识别的转义序列解释为A-Za-z
之后的字符。
回到问题中的问题,请注意\
是输入断言的结尾,即它匹配空字符串。断言不是一个字符,因此将它放在字符类中是没有意义的。如果要在字符类中指定,请使用交替\Z
。
答案 1 :(得分:1)
你误解了\Z
是什么......因为它是模式 锚转义而不是真正的角色;因此,当尝试在字符集合([ ]
)中使用该异常时,该异常有效。
只要\n
存在于数据末尾但它不是\n
字符,它就可用于匹配\n
。
引用MSDN(Anchors in Regular Expressions):
\ Z锚点指定匹配必须在结尾处发生 输入字符串,或在输入字符串末尾的\ n之前。它是 与$ anchor相同,除了\ Z忽略了 RegexOptions.Multiline选项。因此,在多行字符串中,它 只能匹配最后一行的结尾,或\ n。
之前的最后一行请注意\ Z匹配\ n但与\ r \ n(CR / LF字符)不匹配 组合)。要匹配CR / LF,请在正则表达式中包含\ r?\ Z. 图案。