【问题标题】:Regular Expression working in regex tester, but not in c#正则表达式在正则表达式测试器中工作,但不在 C# 中
【发布时间】:2014-07-10 21:59:54
【问题描述】:

我已经搜索了一下,但很难判断这个确切的问题之前是否已经回答过。我知道如果这是重复的,你会告诉我的。

我有一个正则表达式,它匹配一系列一个或多个前面有反斜杠的正整数。例如:\12345 会匹配,但 \1234f 或 12345 不会匹配。

我使用的正则表达式是 ^\\(\d+)$

当我使用各种测试器测试表达式时,它可以工作。例如,参见:http://regex101.com/r/cY2bI1/1

但是,当我在下面的 c# 代码中实现它时,我找不到匹配项。

实现:

public string ParseRawUrlAsAssetNumber(string rawUrl) {
    var result = string.Empty;
    const string expression = @"^\\([0-9]+)$";
    var rx = new Regex(expression);
    var matches = rx.Matches(rawUrl);
    if (matches.Count > 0)
    {
        result = matches[0].Value;
    }
    return result;
}

失败的测试(NUnit):

[Test]
public void ParseRawUrlAsAssetNumber_Normally_ParsesTheUrl() {
    var f = new Forwarder();
    var validRawUrl = @"\12345";
    var actualResult = f.ParseRawUrlAsAssetNumber(validRawUrl);
    var expectedResult = "12345";
    Assert.AreEqual(expectedResult, actualResult);
}

测试的输出:

Expected string length 5 but was 6. Strings differ at index 0.
Expected: "12345"
But was:  "\\12345"
-----------^

有什么想法吗?

分辨率:

感谢大家的意见。最后我根据您的建议采取了以下路线,现在已经通过测试了。

public string ParseRawUrlAsAssetNumber(string rawUrl)
{
    var result = string.Empty;
    const string expression = @"^\\([0-9]+)$";
    var rx = new Regex(expression);
    var matches = rx.Matches(rawUrl);
    if (matches.Count > 0)
    {
        result = matches[0].Groups[1].Value;
    }
    return result;
}

【问题讨论】:

    标签: c# regex


    【解决方案1】:

    问题出在这一行:

    var rx = new Regex(Regex.Escape(expression));
    

    通过转义表达式,您将所有特殊的正则表达式字符转换为文字。调用Regex.Escape(@"^\\(\d+)$") 将返回"\^\\\\\(\\d\+\)\$",这将匹配文字字符串"^\\(\d+)$"

    试试这个:

    var rx = new Regex(expression);
    

    有关如何使用此方法的完整说明和示例,请参阅 MSDN:Regex.Escape


    鉴于您更新的问题,您似乎在这里也遇到了问题:

    result = matches[0].Value;
    

    这将返回 整个 匹配的子字符串,而不仅仅是第一个捕获组。为此,您必须使用:

    result = matches[0].Groups[1].Value;
    

    【讨论】:

    • 糟糕,这是旧版本的代码。我将进行编辑并显示当前版本(问题仍然存在)。
    • 查看我的更新答案。此外,虽然可以编辑问题以提供更多信息,但请尽量不要以在很大程度上使答案无效的方式对其进行编辑。如果必须,请将更新后的代码贴在原始代码下,并清楚地将其标记为编辑。
    • 啊,很好。我不知道 match[0] 会返回完整的子字符串。谢谢。
    • 以这种方式编辑帖子的好处。我以后会避免这种情况。
    • @SergeyBerezovskiy 是的,我在发布初始更新后注意到了这个错误。请再次检查。
    【解决方案2】:

    不要逃避模式。也只需使用Regex.Match,因此您将在这里进行单场比赛。使用Match.Success 检查输入是否与您的模式匹配。并返回 group 值 - 数字在匹配表达式的组中:

    public string ParseRawUrlAsAssetNumber(string rawUrl)
    {            
        const string pattern = @"^\\(\d+)$";
    
        var match = Regex.Match(rawUrl, pattern);
        if (!match.Success)
            return String.Empty;
    
        return match.Groups[1].Value;
    }
    

    【讨论】:

    • +1 对于干净的重写,但if 也不是必需的。即使匹配失败,.Groups[1].Value 也会是一个空字符串。
    • @p.s.w.g 谢谢!不知道默认返回空组的这个技巧。很酷。整个方法可以写成return Regex.Match(rawUrl, @"^\\(\d+)$").Groups[1].Value
    【解决方案3】:

    如果您尝试获取分组结果会怎样?

    match.Groups[1].Value

    当我使用一台真正的计算机时,我会进行测试,但它似乎应该可以工作

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-22
    • 1970-01-01
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多