【问题标题】:.Net Regex split with optional items and greediness.Net 正则表达式拆分为可选项目和贪婪
【发布时间】:2013-03-27 22:08:48
【问题描述】:

这是我试图解析的数据测试样本:

Content1
***
Content2
***
Content3
Content3
***

Content4
***
Content5

***
***
Content6
***
***
***
Content7

简而言之,数据条目在新行上由分隔符字符串分隔。我想获取 Content1、Content2、Content3\r\nContent3、\r\nContent4、Content5\r\n、Content6、Content7。我尝试了一个非常简单的正则表达式 (\r\n)?^\*\*\*$(\r\n)?,它在 RegexBuddy 的 Split with '^$ match at line breaks' 选项和选择的 .Net 风格中为我提供了正确的输出,尽管多个分隔符之间有空字符串,我知道我必须删除手动。但是,下面的 C# 代码:

string regexPattern = string.Format(@"(\r\n)?^{0}$(\r\n)?", Regex.Escape("***"));
var records = Regex.Split(document, regexPattern, RegexOptions.Multiline);

返回整个输入字符串。我哪里错了?

另外,我不明白为什么正则表达式 (\r\n)?\*\*\*(\r\n)?(这并不适合我,因为一个条目可以包含分隔符字符串)返回我 Content1、\r\n、\r\n、Content2、 \r\n 等等。 \r\n 物品不应该被贪婪地抢走吗? RegexBuddy 使用此正则表达式为我提供正确的输出。

【问题讨论】:

    标签: .net regex parsing split regex-greedy


    【解决方案1】:

    1。 $ 到底在哪里匹配?

    主要问题是$ 匹配在\n 字符之前,所以如果\n 之前有任何\r,则需要在模式中指定它。否则,将不返回任何匹配项。你可以在"Content1\r\nContent2\r\nContent3"上测试用"\r$"分割字符串,看看效果。

    只是一个示例,显示在哪里被视为行首 ^ 和行尾 $(在 Multiline 选项下)。第一行是原始字符串(新行和回车分别显示为\n\r),第二行标注了与^$匹配的零长度字符串的位置。

    ***\r\nConte\rn\rt3\r\nCo\nntent3
    ^***\r$\n^Conte\rn\rt3\r$\n^Co$\n^ntent3$
    

    要解决这个问题,我们只需要在$ 之前测试(可选)\r。在下面第 3 节的解决方案中,我测试了可选的\r,因为如果输入文件来自 UNIX 环境,\r 可能不存在。

    2。在Regex.Split 的结果中包含捕获的文本:

    从 .NET Framework 2.0 开始,Regex.Split 将在分隔符处拆分字符串,并且还将捕获的文本包含在结果数组中

    要解决上述问题,只需将捕获组(捕获文本+分组属性)变成非捕获组(?:pattern)(仅分组属性)。

    3。结论

    所以解决办法是:

    var records = Regex.Split(document, @"(?:\r?\n)?^[*]{3}\r?$\n?", RegexOptions.Multiline);
    

    Demo on ideone

    您可以单独处理结果中的空字符串。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-25
      • 2023-04-10
      • 2011-08-29
      相关资源
      最近更新 更多