为什么C#的RegEx类不遵循Environment.NewLine?

4

我正在使用C#交互工具,并且以下是设置:

#r "System.Text.RegularExpressions"
using System.Text.RegularExpressions;
string s = "Number 42" + Environment.NewLine + "and 1 number 3";

我想在每行末尾或字符串末尾的所有数字周围添加括号(42和3都应该被括起来)。
注意:在我的系统上,Environment.NewLine是\r\n。
因此我尝试Regex.Replace(s, "(\\d+)$", "[$0]", RegexOptions.Multiline),但只有3被包裹了。
如果我执行Regex.Replace(s, "(\\d+)\r?$", "[$0]", RegexOptions.Multiline),两个数字都被包装,但一个括号内有额外的\r。所以正则表达式引擎相信Environment.NewLine是\n。
是否有单独为正则表达式设置Environment.NewLine的选项?如果有,那么如何设置?

@WiktorStribiżew 但这不应该是不必要的吗? - NH.
$ 只寻找 \n,但 Environment.NewLine\r\n,所以 (\\d+)$ 不足以匹配,因为 \r 会干扰匹配。 - MonkeyZeus
这里有一个类似的问题:https://dev59.com/emoy5IYBdhLWcg3wWcmg。简而言之,它就是这样工作的,可能是因为正则表达式在 .NET 之前已经有了很长的历史,所以为了与所有其他实现保持一致。 - Evk
@Evk 这是一个值得重复的目标。 - MonkeyZeus
1
实际上,这只是那个线程的部分重复,因为在这里,数字必须用括号括起来,而不带CR符号(当前OP正则表达式实际上并没有做到OP需要的)。 - Wiktor Stribiżew
1个回答

3
$ 锚点是一个正则表达式的构造。而 Environment.NewLine 属性(对于非 Unix 平台为 "\r\n",对于 Unix 平台为 "\n")不在正则表达式库中使用,它是一个独立的属性。
您可以使用
Regex.Replace(s, @"\d+(?=\r?$)", "[$&]", RegexOptions.Multiline)

请参考正则表达式演示

输入图像描述

详细信息

  • \d+ - 1个或多个数字
  • (?=\r?$) - 后面跟一个可选回车符,然后是行尾。

重点在于,当您使用RegexOptions.Multiline时,$锚定符匹配的是LF(\n)符号的右侧位置。没有办法重新定义这种行为。在Windows中,Environment.NewLine插入CRLF换行符序列,因此您得到\r\n作为行尾。因此,在$之前添加\r?是一种有效的方法来匹配行尾位置。


那么$和Environment.NewLine之间有什么关系吗?没有吗? - NH.
1
@NH。$是一个正则表达式构造。Environment.NewLine(“*对于非Unix平台为\r\n,对于Unix平台为\n*”)是.NET属性,它不是正则表达式库的一部分,也没有从中引用。 - Wiktor Stribiżew

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接