.net 为什么Regex.Escape支持数字符号和空格?

2j4z5cfb  于 2023-11-20  发布在  .NET
关注(0)|答案(3)|浏览(122)

据我所知,Regex.Escape通过自动将包含regex Meta字符的模式转换为该模式的“转义”版本,来帮助生成regex模式。
因此,如果你只想匹配abc.abc,你不能把它作为一个模式,因为句点(或点)是一个正则表达式Meta字符,恰好是一个空格。正则表达式.转义方便地将其转换为abc\.abc,它可以用作一个正则表达式模式,而不会把点用作空格。
Regex.Escape“escapes”14个字符.
转义最小字符集(,,+,?,|、{、[、(、)、^、$、.、#和白色空格),方法是将它们替换为转义码。
然而,似乎只有12个字符不匹配自己。字符以外的这些 * 做 * 匹配自己。
. $ ^ { [(|)
+?
This is the link to the reference that says there are 12 chars that do not match themselves.
准确的措辞使这一主张...
字符或序列列中列出的字符以外的字符在正则表达式中没有特殊意义;它们自己匹配。
不同的是Regex.Escape文档中提到的最后2个字符,它们是空格和数字符号。为什么Regex.Escape支持超过12个不匹配的字符?

bvk5enib

bvk5enib1#

在自由间距模式(RegexOptions.IgnorePatternWhitespace)下,#和空白本身不匹配:#开始注解,空白被忽略。
the documentation page you linked to上也有这样的注解:
如果正则表达式模式包含数字符号(#)或文本空白字符,则在启用RegexOptions.IgnorePatternWhitespace选项的情况下分析输入文本时,必须对这些字符进行转义。
例如,这完全等同于print\('Loremipsum'\)

(?x)
print\('Lorem ipsum'\)  (?#Inline comment)
 # Comment

字符串
. while this matches "print('Lorem ipsum')\n # Comment"\n is an actual linebreak):

(?x)
print\('Lorem\ ipsum'\)  (?#Inline comment)\
\ \#\ Comment

ni65a41a

ni65a41a2#

简单的答案是,空格和磅符号,如果在正则表达式中转义,工作相同
在这两种情况下,都可以忽略空白模式。
保留未转义,根据模式更改含义。
这个答案不需要正则表达式声明。

deyfvvtc

deyfvvtc3#

感谢@InSync让我知道RegexOptions.IgnorePatternWhitespace选项。也感谢@sln。这里是一个更长的答案。
文档中的12个Meta字符可以被描述为普通的元字符。Regex.Escape支持额外的2个字符(空白和numberSign)的原因是因为当使用RegexOptions.IgnorePatternWhitespace定义模式时,额外的2个字符成为元字符。
在“正常”模式下,即没有RegexOptions.IgnorePatternWhitespace,numberSign和空白都是文字,也就是说,它们不是Meta字符。
RegexOptions.IgnorePatternWhitespace允许您编写自文档模式。具体来说,该选项允许引入不会成为模式一部分的空格,并在numberSign之后引入不会成为模式一部分的注解。有效地,它将空格转换为将被忽略的模式元字符。有效地,它将numberSign转换为将被忽略的模式元字符,并且后面的所有内容都将被ignored.我们引入了要忽略的字符,因为它们是文档。
使用这个选项意味着你必须转义空格才能让它是文字。使用这个选项意味着你必须转义numberSign才能让它是文字。

Regex r;
        
r = new Regex("a a a #comment"); // in normal mode whitespace is literal and numberSign is literal
Debug.Assert(r.IsMatch("aaa") == false);
Debug.Assert(r.IsMatch("a a a #comment"));

// in normal mode escaping whitespace and escaping numberSign are needless but it has no harmful effect
// interpretation... escaping a meta char means make it literal
// in normal mode whitespace is not a meta char so the effect is to take a literal and make it literal which has no effect
// in normal mode numberSign is not a meta char so the effect is to take a literal and make it literal which has no effect
r = new Regex(Regex.Escape("a a a #comment"));
Debug.Assert(r.IsMatch("aaa") == false);
Debug.Assert(r.IsMatch("a a a #comment"));

r = new Regex("a a a #comment", RegexOptions.IgnorePatternWhitespace); // the option renders the whitespace and comment insignificant
Debug.Assert(r.IsMatch("aaa"));
Debug.Assert(r.IsMatch("a a a #comment") == false);

// escape whitespace and escape numberSign by human coded escape sequences
r = new Regex(@"a\ a\ a\ \#comment", RegexOptions.IgnorePatternWhitespace);
Debug.Assert(r.IsMatch("aaa") == false);
Debug.Assert(r.IsMatch("a a a #comment"));

// escape whitespace and escape numberSign by using Regex.Escape
r = new Regex(Regex.Escape("a a a #comment"), RegexOptions.IgnorePatternWhitespace);
Debug.Assert(r.IsMatch("aaa") == false);
Debug.Assert(r.IsMatch("a a a #comment"));

字符串
另外.

r = new Regex("a-z[P-R]");


第一个连字符是文字,第二个连字符定义了一个组,该模式正好匹配一个字符。

相关问题