C#正则表达式仅使用大写字符查找和替换链接,并且不匹配排除项

Ser*_*gey 1 c# regex

我正在努力完成一个简单的正则表达式任务.我想用以下排除项替换文本中具有大写字母和小写字母的所有href链接.

例如

href="/image-ZOOM.aspx?UPPERcasE=someThing" 匹配并替换为

href="/image-zoom.aspx?uppercase=something"

href="/image-coorect.aspx" - 不匹配

它也会排除href="javascript:function();"并且不会在<% %>标签之间小写任何内容.

例如:

href="/images/PDFs/<%=Product.ShortSku %>.pdf" 被翻译成

href="/images/**pdfs**/<%=Product.ShortSku %>.pdf"

我尝试了类似的东西,href="([^"]*[A-Z]+[^"]*)"但仍然匹配所有小写的链接.你能不能发光一下.

谢谢!

Ahm*_*eed 6

棘手的部分是你的<% ... %>要求.一旦将URL的每个部分分成组,这实际上非常简单.

href="/images/PDFs/<%=Product.ShortSku %>.pdf"
      |_____1_____||__________2_________||_3_|
Run Code Online (Sandbox Code Playgroud)
  1. 该组必须存在.
  2. 该组是可选的.
  3. 如果组2不存在,那么组3将不存在,在这种情况下组1匹配整个href内容.如果存在组2,则组3将是href内容的剩余部分.

通过理解上面的内容,你最终得到了其他字符串:

href="/image-ZOOM.aspx?UPPERcasE=someThing"
      |________________1_________________|
Run Code Online (Sandbox Code Playgroud)

我最终得到了这个使用命名组的模式:

@"href=""(?!javascript:)(?=[^""]*[A-Z])(?<Start>[^""<]+)(?<Special><%[^""]+%>)?(?<End>[^""]*)"""
Run Code Online (Sandbox Code Playgroud)
  • href="" :匹配href并打开双引号.
  • (?!javascript:) :负面预测忽略javascript函数.
  • (?=[^""]*[A-Z]):积极向前看,在内容中找到大写字母.将[^""]*匹配任何字符不是一个双引号.这样做是为了避免超出内容的末尾并贪婪地匹配非预期的内容.
  • (?<Start>[^""<]+):与任何char匹配的命名组,只要它不是双引号或开括号括号.查看之前的描述 - 角括号检查确保<% ... %>在遇到内容时停止.如果没有,模式将继续,直到遇到结束双引号.
  • (?<Special><%[^""]+%>)?:用于捕获内容的可选命名组<% ... %>.尾随?标记将整个组标记为可选.
  • (?<End>[^""]*):命名组以匹配任何剩余内容.请注意,我用*它来匹配零个或多个内容.这允许模式的这一部分在特殊组不存在的情况下充当可选匹配.
  • "" :收盘双报价.

示例代码:

string[] inputs =
{
    "href=\"/image-ZOOM.aspx?UPPERcasE=someThing\"", // match
    "href=\"/image-coorect.aspx\"",  // no match, lowercase
    "href=\"javascript:function();\"", // no match, javascript
    "href=\"/images/PDFs/<%=Product.ShortSku %>.pDf\"", // bypass <% %> content
};

string pattern = @"href=""(?!javascript:)(?=[^""]*[A-Z])(?<Start>[^""<]+)(?<Special><%[^""]+%>)?(?<End>[^""]*)""";

foreach (var input in inputs)
{
    Console.WriteLine("{0,6}: {1}", Regex.IsMatch(input, pattern), input);
    string result = Regex.Replace(input, pattern,
                        m => "href=\""
                            + m.Groups["Start"].Value.ToLower()
                            + m.Groups["Special"].Value
                            + m.Groups["End"].Value.ToLower()
                            + "\"");
    Console.WriteLine("Result: " + result);
    Console.WriteLine();
}
Run Code Online (Sandbox Code Playgroud)

这使用lambda代替MatchEvaluator.基本上我们正在重建字符串并引用命名组,改变我们想要修改的组的大小写.这段代码的一个微妙的关键是,如果一个组不匹配,我们仍然可以引用它,它只会给我们一个空字符串.此外,这可能在代码中并不明显,但是当匹配失败时,原始字符串将不加改变地返回Regex.Replace.