一个正则表达式工作,另一个没有

时间:2012-10-09 17:48:03

标签: c# .net regex

我正在寻找看起来像abc/def的数据。文本周围可能有空格,因此以下所有内容都有效:abc__/_def__abc/__def__。 (使用下划线可视化空格。)

我想出了这个正则表达式:

(?<=\s*)abc\s*\/\s*def(?=\s*|^)

这可以找到匹配。我最近才开始前瞻并尝试使用此表达式从匹配项中排除/周围的空格(因此abc__/_def会产生匹配abc/def):

(?<=\s*)abc(?=\s*)\/(?=\s*)def(?=\s*|^)

这个表达不起作用 - 我显然误解了一些关于前瞻的东西。有人可以解释这两个表达式之间的区别吗? (甚至可能我正在尝试做什么?在阅读了Regex文档之后,我认为它是,但也许我错了。)

3 个答案:

答案 0 :(得分:1)

任何.NET正则表达式返回的匹配都是原始字符串的连续子字符串。这意味着您无法摆脱“/”字符周围的空间。你可以摆脱外面的空间。

一种好的方法是使用命名组匹配abcdef并使用

提取该信息
Match m = ...;
var part1 = m.Groups["part1"].Value;
var part2 = m.Groups["part2"].Value;

试试这个:^\s*(?<part1>\w+)\s*/\s*(?<part2>\w+)\s*$

通常情况下,正则表达式在命名组中更自然,没有外观。

答案 1 :(得分:1)

当您尝试查找某些内容并将其从结果中排除时,会使用前瞻性等。

如果斜杠和abc之间有空格,例如前瞻会找到它们,但是由于你排除它们,所以它不能选择空格作为结果。没有与表达式匹配的连续字符串,因此没有选择字符串。

你想从选择中排除空格,据我所知你不能这样做。

你可以根据需要选择abc。

(?<=\s*)abc(?=(\s*\/\s*def(\s*|^)))

但是你不能在不同的地方传播你的选择。

如果您之后必须过滤您的选择,我建议使用stringbuilder并迭代结果(出于速度原因)。

    public Boolean TryRegexMatchRemovedWhiteSpace(string input, string expr, out String matched)
    {

        Match m = Regex.Match(input, expr);
        if (m.Success)
        {
            StringBuilder r = new StringBuilder(m.Value.Length);
            foreach (var c in m.Value)
            {
                if (!char.IsWhiteSpace(c))
                {
                    r.Append(c);
                }
            }
            matched = r.ToString();
        }
        else
        {
            matched = "";
        }
        return m.Success;
    }

答案 2 :(得分:0)

这是因为它向前看,但在尝试匹配时不包括它。所以,如果你使用

<强> ABC(?= \ S *)

它会匹配 的 ABC abc ___

但两个案例的匹配组[0]都是'abc'。

所以,你的第二个正则表达式只匹配abc / def,但不是abc __ / _ def

读取器