【问题标题】:Regex replace help正则表达式替换帮助
【发布时间】:2009-01-27 17:34:22
【问题描述】:

使用 .NET 框架,我试图用单斜杠替换字符串中的双斜杠字符,但它似乎删除了一个额外的字符,我不知道为什么。

我有一个字符串:

http://localhost:4170/RCRSelfRegistration//Default.aspx

我的正则表达式是:

[^(://|:\\\\)](\\\\|//|\\/|/\\)

而返回值为:

http://localhost:4170/RCRSelfRegistratio/Default.aspx

可以看到 RCRSelfRegistration 中的 n 已经被移除了。我不知道为什么。

/// <summary>
/// Match on double slashes (//, \\, /\, \/) but do not match :// or :\\
/// </summary>
private const string strMATCH = @"[^(://|:\\\\)](\\\\|//|\\/|/\\)";

/// <summary>
/// Replace double slashes with single slash
/// </summary>
/// <param name="strUrl"></param>
/// <returns></returns>
public static string GetUrl(string strUrl)
{
    string strNewUrl
    System.Text.RegularExpressions.Regex rxReplace =
      new System.Text.RegularExpressions.Regex(strMATCH);

    strNewUrl = rxReplace.Replace(strUrl, "/");

    return strNewUrl;
}

【问题讨论】:

    标签: .net regex


    【解决方案1】:

    [^(://|:\\\\)] 不像你想象的那样工作。

    [] 是一个字符范围 - 它匹配该范围中包含的单个字符。

    [^:] 将匹配除冒号以外的任何字符。这可能更接近您想要的。

    你可能真正想要的是zero-width lookbehind assertion:(?&lt;!:)

    【讨论】:

      【解决方案2】:

      你的正则表达式“[^(://|:\\)]”的第一部分匹配任何不是“(:/|\”的字符(正如tomalak指出的那样,negset匹配其中的所有字符,没有进一步的处理逻辑),其中包括紧接在“//default.aspx”之前的“n”——它不是一个零宽度断言。

      您可能想要做的是将模式的那部分更改为零宽度的lookbehind,以确保斜线字符前面没有冒号。

      【讨论】:

      • 我明白你在说什么。我已将字符串简化为 "[^:](\\\\|//|\\/|/\)" 但你能告诉我零宽度后视的语法吗?
      • 现在到处都是。 =)
      • 在你的情况下 - "(?
      • 事实上,"[^(://|:\\)]" 匹配除了这些字符之外的任何字符:"(|:/\" - 它是一个字符类,而不是一个交替,甚至如果它看起来像一个。
      • 解决给定问题的最小正则表达式可能是:“(?
      【解决方案3】:

      你需要的是一个消极的观察组,像这样:

      (?<!:)(\\\\|//|\\/|/\\)
      

      【讨论】:

        【解决方案4】:

        正则表达式的否定部分 [^(://|:\\)] 与 n 匹配,因此将其删除。

        【讨论】:

          【解决方案5】:

          您是否尝试过使用字符串的替换方法。它不像正则表达式替换那么优雅,但只要你不在一个循环中对巨大的字符串执行数百次它就可以达到你的目的:

          string myString = oldString.Replace(@"\\", @"\").Replace("//", "/");
          

          否则,您可能会在 Regex 上花费大量时间。

          【讨论】:

            【解决方案6】:

            我认为你只需要一个简单的字符串替换循环。将所有“//”替换为“/”。您需要一个函数来保存搜索位置并让您遍历字符串。一旦到达字符串的末尾,请再次执行此操作,直到您在通过时不进行任何替换。

            例如:

            ///a//a/a////

            通过 1

            //a/a/a//

            通过 2

            /a/a/a/

            【讨论】:

            • 这会非常慢,这就是正则表达式的任务类型
            • 我现在闭嘴,我正确地阅读了这个问题。需要更多的咖啡。
            猜你喜欢
            • 2011-05-27
            • 2010-10-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-01-08
            • 1970-01-01
            • 2011-06-10
            相关资源
            最近更新 更多