仅具有完全匹配的正则表达式

时间:2018-11-21 17:12:01

标签: .net regex lookahead lookbehind

我知道这个主题很烂,而且我阅读了相关的答案...
但是,我会问...
我输入了以下格式的字符串:

3#0.01, 2#0.5, 1#-10, -2#~ 

这是由逗号分隔的值的列表。
我可以使用下一个表达式捕获所有值:

(([-+]?\d+)#([-+]?\d*\.?\d+|~))+ 

一切正常。

但是如果输入字符串中出现任何错误,我希望没有匹配项,例如:

MISTAKE3#0.01, 2#0.5, 1#-10, -2#~AND_HERE_MISTAKE_TOO 

不幸的是,^和$符号在这里没有帮助。
所以我的问题是:如果输入字符串的某些部分无效,如何停止匹配。
谢谢。

以下是代码段: https://regex101.com/r/Xih0Qk/2

1 个答案:

答案 0 :(得分:2)

在.NET中,您可以使用具有无限宽度后缀的正则表达式(如果需要在此处移植相同的解决方案,则最新的ECMAScript 2018支持的JavaScript环境也支持该正则表达式)。正则表达式看起来像

(?<=^(?:[-+]?\d+#(?:[-+]?\d*\.?\d+|~),\s)*)[-+]?\d+#(?:[-+]?\d*\.?\d+|~)(?=(?:,\s[-+]?\d+#(?:[-+]?\d*\.?\d+|~))*$)

请参见online regex demo

在代码中,从变量构建模式更容易:

var block = @"[-+]?\d+#(?:[-+]?\d*\.?\d+|~)";   // Block/unit pattern
var pattern = $@"(?<=^(?:{block},\s)*){block}(?=(?:,\s{block})*$)";
var results1 = Regex.Matches("3#0.01, 2#0.5, 1#-10, -2#~", pattern)
    .Cast<Match>().Select(x => x.Value);
if (results1.Count() > 0)
    Console.WriteLine(string.Join(", ", results1));
var results2 = Regex.Matches("MISTAKE3#0.01, 2#0.5, 1#-10, -2#~AND_HERE_MISTAKE_TOO", pattern)
    .Cast<Match>().Select(x => x.Value);
if (results2.Count() > 0)
    Console.WriteLine(string.Join(", ", results2));

请参见C# demo online。输出(仅匹配正确的字符串):

3#0.01, 2#0.5, 1#-10, -2#~

模式说明

  • (?<=^(?:{block},\s)*)-向后的正向查找,仅与紧随字符串开头0+次出现的{block}模式,紧跟,和1个空格的位置之前的位置相匹配
  • {block}-您要匹配的块/单位模式
  • (?=(?:,\s{block})*$)-一个正向超前匹配,与位置相匹配,紧随其后出现0+次,,空格和{block}模式,直到字符串结尾。
  • li>