我知道这个主题很烂,而且我阅读了相关的答案...
但是,我会问...
我输入了以下格式的字符串:
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
答案 0 :(得分:2)
在.NET中,您可以使用具有无限宽度后缀的正则表达式(如果需要在此处移植相同的解决方案,则最新的ECMAScript 2018支持的JavaScript环境也支持该正则表达式)。正则表达式看起来像
(?<=^(?:[-+]?\d+#(?:[-+]?\d*\.?\d+|~),\s)*)[-+]?\d+#(?:[-+]?\d*\.?\d+|~)(?=(?:,\s[-+]?\d+#(?:[-+]?\d*\.?\d+|~))*$)
在代码中,从变量构建模式更容易:
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}
模式,直到字符串结尾。