1

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

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

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

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

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

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

4

3 回答 3

1

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

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

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

如果你愿意,你可以只选择 abc。

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

但是您不能将您的选择分散到不同的区域。

如果您必须在之后过滤您的选择,我建议使用字符串生成器并像这样遍历结果(出于速度原因)。

    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;
    }
于 2012-10-09T18:12:28.593 回答
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*$

通常,正则表达式对于命名组和没有环视更自然。

于 2012-10-09T17:55:00.677 回答
0

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

abc(?=\s*)

它将匹配 abcabc___

但对于这两种情况,匹配组 [0] 都是“abc”。

因此,您的第二个正则表达式将仅匹配 abc/def,但不匹配 abc__/_def

读者

于 2012-10-09T17:59:40.880 回答