【问题标题】:treating \r as \n in c# regex在 c# 正则表达式中将 \r 视为 \n
【发布时间】:2013-05-09 02:48:35
【问题描述】:

我有一个 c# 函数,可以在输入侧查找文本模式并进行一些处理。 (我使用的是3.5版本的.net框架)

public void func(string s)
{
    Regex r = new Regex("^\s*Pattern\s*$", RegexOptions.Multiline | RegexOptions.ExplicitCapture );
    Match m = r.Match(s);
    //Do something with m
}

函数的使用可能如下所示

string s = "Pattern \n Pattern \n non-Pattern";
func(s);

但是,我发现有时我的输入看起来更像这样

string s = "Pattern \r Pattern \r non-Pattern"
func(s);

而且它没有被匹配。有没有办法让\r 在正则表达式中被视为\n?我想我总是可以用\ns 替换所有\rs,但我希望如果我能让正则表达式一次完成所有操作,我可以尽量减少操作。

【问题讨论】:

    标签: c# regex


    【解决方案1】:

    如果将 /n 或 /r 放在字符集中,则可以匹配它们

    [\n\r]
    

    将匹配 \n 或 \r 字符之一

    【讨论】:

      【解决方案2】:

      不幸的是,当我遇到类似情况时,我发现唯一可行的情况是我只使用正则表达式进行两次传递(就像你希望避免的那样),第一次规范化行尾然后第二次可以像往常一样进行搜索,没有办法让Multiline 仅触发我能找到的/r

      public void func(string s)
      {
          s = Regex.Replace(s, @"(\r\n|\n\r|\n|\r)", "\r\n");
          Regex r = new Regex("^\s*Pattern\s*$", RegexOptions.Multiline | RegexOptions.ExplicitCapture );
          Match m = r.Match(s);
          //Do something with m
      }
      

      【讨论】:

      • 是的,我想我将不得不做类似的事情。我想知道为什么$\r 不匹配?感觉应该。
      • 因为\r 不被视为 Windows 行尾,而 .NET 是一种 Windows 技术。 “多行”的定义不是 regex 的一个特性,而是 .NET 添加到 regex 的特性,因此没有可遵循的标准。
      • 我认为 2 pass 解决方案有意义且更易于维护。只是想知道:为什么 \n\r 被认为是 1 行的结尾?
      • 我只是想获取所有可能的格式错误数据的组合,我想我以前没有遇到过,但\r 不被认为是任何modern OS either 的有效结尾并运行到只有 \r 的数据源是促使我编写从上面复制并粘贴上述代码的 sn-p 的原因。谁知道呢,也许有一天我会遇到来自 BBC Micro 系统的数据 :)
      • 我当然没想到\r 会成为一个新行,并将其从我的单元测试中排除(所有测试都通过\n!)。然而,自从\r 出现在我期待的\n 的位置后,我的代码开始出现故障。
      【解决方案3】:

      根据文档Anchors in Regular Expression

      • ^Multiline 模式下将匹配输入字符串的开头或行的开头(由\n 定义)。
      • $Multiline 模式下将匹配输入字符串的结尾,或者就在\n 之前。

      如果您的目的是重新定义锚点以使用\r\n 定义一条线,那么您必须使用look-ahead 和look-behind 来模拟它。

      • ^ 应该用 (?<=\A|[\r\n]) 模拟
      • $ 应该用(?=\Z|[\r\n]) 模拟

      请注意,上面的模拟将考虑 \r\n 有 3 个行首和 3 个行尾。 1 个行首和 1 个行尾由字符串的开头和结尾定义。其他 2 个行首和 2 个行尾由 \r\n 定义。

      【讨论】:

      • 请更新您关于如何定义线的问题。此答案以\r\n 结尾时定义一行。
      • 我不确定完全理解你的意思。对于我的应用程序\r\n,一两行没有任何区别。只要Pattern作为输入文本的整行存在,我就可以匹配Pattern这样的每一行。
      • @MarkB42:这取决于你的模式。现在无法举个例子,但我相信某些模式会有所不同。
      猜你喜欢
      • 2010-09-07
      • 2023-03-21
      • 2023-03-14
      • 1970-01-01
      • 2011-10-02
      • 1970-01-01
      • 2023-03-09
      相关资源
      最近更新 更多