仅具有完全匹配的正则表达式
Regular expression with full match only
我知道这个老生常谈的主题,我阅读了相关答案...
不过,我会问...
我有下一种格式的输入字符串:
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 中,您可以使用具有无限宽度后视的正则表达式(它在最新的 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/unit 模式
(?=(?:,\s{block})*$)
- 匹配位置的正前瞻,紧接着出现 0 次以上的 ,
、空格和 {block}
模式,直到字符串的末尾。
我知道这个老生常谈的主题,我阅读了相关答案...
不过,我会问...
我有下一种格式的输入字符串:
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 中,您可以使用具有无限宽度后视的正则表达式(它在最新的 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/unit 模式(?=(?:,\s{block})*$)
- 匹配位置的正前瞻,紧接着出现 0 次以上的,
、空格和{block}
模式,直到字符串的末尾。