我知道这个陈词滥调的主题,并且我阅读了相关答案......
不过,我会问...
我有以下格式的输入字符串:
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
不幸的是 ^ 和 $ 符号在这里没有帮助。
所以我的问题是:如果输入字符串的某些部分无效,我如何才能停止匹配。
谢谢。
最佳答案
在.NET中,您可以使用具有无限宽度lookbehinds的正则表达式(如果您需要在其中移植相同的解决方案,最新的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}
- 要匹配的 block /单元模式 -
(?=(?:,\s{block})*$)
- 正向前瞻,与紧随其后出现 0 次以上,
的位置相匹配、一个空格和一个{block}
模式直到字符串末尾。
关于.net - 仅完全匹配的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53417330/