.Net正则表达式与可选项目和贪婪分开

时间:2013-04-05 13:10:44

标签: .net regex parsing split regex-greedy

以下是我正在尝试解析的数据的测试样本:

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中使用'^ $ match at line breaks'选项和.Net flavor选择给我正确的输出,虽然在多个分隔符之间有空字符串,我知道我有手动删除。但是,以下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使用此正则表达式为我提供了正确的输出。

1 个答案:

答案 0 :(得分:1)

1。 $到底匹配的位置是什么?

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

只是一个示例,用于显示行^的开头和行$的结尾(在Multiline选项下)。第一行是原始字符串(新行和回车符分别显示为\n\r),第二行注释了由{{1}匹配的零长度字符串的位置}和^

$

要解决此问题,我们只需要在***\r\nConte\rn\rt3\r\nCo\nntent3 ^***\r$\n^Conte\rn\rt3\r$\n^Co$\n^ntent3$ 之前测试(可选)\r。在下面第3节的解决方案中,我测试了可选的$,因为如果输入文件来自UNIX环境,\r可能不存在。

2。在\r

的结果中包含捕获的文本

在.NET Framework 2.0中,Regex.Split会将字符串拆分为分隔符,而也会在结果数组中包含捕获的文本

要解决上述问题,您只需将捕获组(捕获文本+分组属性)转换为非捕获组 Regex.Split(分组)仅属性)。

3。结论

所以解决方案是:

(?:pattern)

Demo on ideone

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