【问题标题】:Replace multiple occurrences of same string in href using Regular Expressions使用正则表达式替换href中相同字符串的多次出现
【发布时间】:2014-09-17 14:17:55
【问题描述】:

我们的 CMS(我想是正确的)在 URL 中编码逗号字符。因此,CMS 不是“?values=1,2,3”,而是呈现“?values=1%2c2%2c3”。这本身不是问题,但是这些链接指向的外部系统无法处理编码的逗号,并且只有在我们在查询字符串中传递实际逗号时才有效。

我们已经有了一个正则表达式清理工具,可以处理 HTML 预渲染并清理不符合 XHTML 的标记。这是在 ASP.Net v2 上运行的旧 CMS。

我的问题是,将所有出现的“%2c”替换为逗号需要什么正则表达式,但仅限于该文本存在于锚标记中的地方。我已经能够轻松地换出 %2c 的所有实例,但是如果该字符串碰巧用于非 URL 目的,则存在损坏页面的风险。

我正在使用 .Net 和 System.Text.RegularExpressions。我们有一个包含所有查找和替换规则的 XML 文件。这会在运行时加载并清理 HTML。每条规则包括:

  • 要查找的文本 - 例如"<script>"
  • 要替换的文本 - 例如"<script type='text/javascript'>"

然后我们有一些 C# 循环遍历每个规则并执行以下操作:

// HTML = full page HTML
Regex regex = new Regex(searchTxt, RegexOptions.IgnoreCase);
HTML = regex.Replace(HTML, replaceTxt);

就这么简单。我只是无法为我们的特定场景获得正确的正则表达式语法。

非常感谢您的帮助。

这是一个完整的 C# 控制台应用程序,希望能解释我的场景

class Program
{
    static void Main(string[] args)
    {
        string html = GetPageHTML();
        string regexString = "(<a href=).*|(%2c)";
        string replaceTxt = ",";

        RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.Multiline;
        Regex regex = new Regex(regexString, options);

        // We are currently using a simple regex.Replace
        string cleanHTML = regex.Replace(html, replaceTxt);

        // But for this example should we be doing something with the Matches collection?
        foreach (Match match in regex.Matches(html))
        {
            if (match.Success)
            {
                // do something?
            }
        }

    }

    private static string GetPageHTML()
    {
        return @"<html>
                    <head></head>
                    <body>
                        <a title='' href='http://www.testsite.com/?x=491191%2cy=291740%2czoom=6%2cbase=demo%2clayers=%2csearch=text:WE9%203QA%2cfade=false%2cmX=0%2cmY=0' target='_blank'>A link</a>
                        <p>We wouldn't want this (%2c) to be replaced</p>
                    </body>
                </html>";
    }
}

【问题讨论】:

  • HttpServerUtility.UrlDecode 试过了吗?
  • 没有。我在内存中没有可以执行此操作的字符串实例。我只有整个 HTML 页面,我可以在其中有效地使用正则表达式进行查找和替换。

标签: asp.net .net regex replace


【解决方案1】:

如果 .net 支持 pcre 正则表达式,你可以这样做:

^(?!<a href=").*(*SKIP)(*FAIL)|(%2c)

这就是你想要的。以上正则表达式将仅匹配锚标记内的%2c。但是,如果您使用正则表达式、正则表达式丢弃技术加上一些逻辑,您也可以达到同样的效果。

如果您使用下面的正则表达式,您可以匹配 %2c 并捕获锚标记内的 %2c 字符串:

^(?!<a href=").*|(%2c)

Working demo

因此,您可以做的是添加逻辑并检查捕获组内容是否等于%2c,在这种情况下意味着它与锚标记中的%2c 匹配。然后你可以用逗号替换它。

【讨论】:

  • @j.strugnell 在我的回答中我解释的是使用正则表达式技术。在屏幕截图中,您可以看到绿色表示您关心的匹配项,蓝色表示您不关心的匹配项。因此,您使用此正则表达式来捕获您想要使用捕获组的字符串。您需要使用的逻辑是:if (captureGroup is not empty) then replace the string
  • 感谢您的澄清。明天我会进一步看一下,如果我破解它,请告诉你。再次感谢。
  • 对不起,我不能让它工作。我将编辑问题以包含一些示例 C# 控制台代码,以帮助人们复制我的场景。
  • 为此,我们决定替换页面中的所有 %2c 实例,因为我无法让它仅定位锚标记。感谢您的帮助@Fede,我无法将您的答案打勾为“the”答案,因为我无法让它发挥作用。但这很可能是由于我自己缺乏正则表达式技能……;0)谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-27
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
相关资源
最近更新 更多