承诺,我的正则表达式问题的最后一段时间了。 ..Really。
当我不应该在某些比赛中获得新线时,我确信这是我误解的东西,或者,我得到的数据并不是我所期望的。 (哪有可能..!)
我有一个正则表达式定义:
new Regex(@"^\s*[0-9]{4}[A-Z]{2}[\s\*]\s*(?<token>.*?)\-(?<value>.*?)$", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);
我得到的文档/字符串格式化为偶尔的行,如:
0000AA Token1 - Value
0000AA Token2 - Value
0000AA Token3 - Value
0000AA Another Tok- Value
当我按照这样的顺序获得所有令牌时,上面的正则表达式效果很好。我得到四场比赛:
Match# <token> <value>
1 Token1 Value
2 Token2 Value
3 Token3 Value
4 Another Tok Value
这很好。但是,有时用户会向我发送一个文件,其中令牌偶尔会有缺失行,如:
0000AA Token1 - Value
0000AA Token2 - Value
0000AA Token3 - Value
0000AA
0000AA Another Tok- Value
发生这种情况时,我的正则表达式会给我以下值:
Match# <token> <value>
1 Token1 Value
2 Token2 Value
3 Token3 Value
4 0000AA Another Tok Value
我知道为什么,它与#4的令牌相匹配,从它上面的一行开始。但是,当我将“令牌”分组更改为(?<token>[^\n]*?)
时,我仍然会在“令牌”中获得相同的值。
我觉得我错过了一些明显的东西,因为如果。当它不应该匹配换行符时,更多的人比葡萄干更加惹恼它。我检查了传入的字符串 - 换行符是\n
,而不是\r\n
,但是想知道是否还有其他问题。
再次干杯 - 麦克
答案 0 :(得分:4)
问题出现在开头的字母数字代码之后的 \ s 中; \ s 也匹配换行符,您不想这样做。您基本上需要匹配 \ s AND NOT \ n 。这不能用正则表达式表达,但如果使用DeMorgan定理,则可以重写此表达式:
\s AND NOT \n = NOT(NOT \s OR \n)
事实证明 NOT \ s 可以写成 \ S :
\s AND NOT \n = NOT(NOT \s OR \n) = NOT(\S OR \n)
这很容易表达为正则表达式:
\s AND NOT \n = NOT(NOT \s OR \n) = NOT(\S OR \n) = [^\S\n]
因此,使用 [^ \ S \ n] 代替 \ s ,这意味着匹配除换行符之外的所有内容,并取消\ s的否定
我在同一区域做了一些其他更改,因为我觉得有些东西不是必需的。如果您认为可以,可以将其添加回来。
Regex re = new Regex(@"^[0-9]{4}[A-Z]{2}[^\S\n]*(?<token>.*?)\-(?<value>.*?)$", RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);