gpt4 book ai didi

java - RegEx匹配没有特定属性的 html标签

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:05:08 28 4
gpt4 key购买 nike

在 Java 中我需要匹配 <a>字符串中没有 href 属性的标签。例如在以下字符串中:

text <a class="aClass" href="#">link1</a> text <a class="aClass" target="_blank">link2</a> text

它不应该匹配 <a class="aClass" href="#">link1</a> (因为它包含 href)但它应该匹配 <a class="aClass" target="_blank">link2</a> (因为它不包含 href)。

我设法构建了 RegEx 来匹配我的标签:

<a[^>]*>(.*?)</a>

但我不知道如何用 href 消除标签

(我知道我可以使用 HTML 解析器等,但我需要使用 RegEx 来做到这一点。

最佳答案

描述

小心像 <a[^>]* 这样的正则表达式因为这些也会匹配其他以 a 开头的有效 html 标签例如<abbr><address> .也只是简单地寻找字符串 href 的存在不够好,因为该字符串可能位于另一个属性的值内,例如 <a class="thishrefstuff"... ,或另一个属性的一部分,如 <a hreflang="en"...

这个表达式将:

  • 匹配所有 anchor 标签<a ... </a>不包含 href属性。
  • 它将强制标签名称为 a而不是仅以字母 a 开头的标签喜欢<address>
  • 忽略也有子字符串href 的属性嵌入在属性名称中,例如有效的 hreflang='en'或弥补Attributehref="some value" .
  • 忽略所有格式正确的属性值部分内的所有字符,如 bogus='href=""'

<a(?=\s|>)(?!(?:[^>=]|=(['"])(?:(?!\1).)*\1)*?\shref=['"])[^>]*>.*?<\/a>

enter image description here

展开

  • <a(?=\s|>)匹配打开标签并确保标签名称后的下一个是空格或右括号,这会强制名称为 a而不是别的
  • (?!如果我们在这个标签中找到一个 href 那么这种类型的标签不是我们正在寻找的标签
    • (?:启动非捕获组以遍历标记内的所有字符
    • [^>=]匹配所有防止正则表达式引擎离开标记的非标记结束字符,以及防止引擎继续盲目匹配所有字符的非等号
    • |
    • =(['"])匹配等号后跟左双引号或单引号。报价被捕获到第 2 组中,以便稍后可以正确配对
    • (?:(?!\1).)*匹配不是匹配开引号的闭引号的所有字符
    • \1匹配正确的引号
    • )*?关闭非捕获组并根据需要经常重复,直到
    • \shref=['"]匹配所需的 href 属性。 \s=["']确保属性名称只是 href
    • )关闭负面前瞻
  • [^>]*>.*?<\/a>从开始到结束匹配整个字符串

Java 代码示例:

输入文字

<abbr>RADIO</abbr> text <a class="aClass" href="#">link1</a> text <a bogus='href=""' class="aClass" target="_blank">link2</a> text

代码

如果您希望在替换函数中使用它来删除非 href-anchor 标签,那么只需将所有匹配项替换为空即可。

import java.util.regex.Pattern;
import java.util.regex.Matcher;
class Module1{
public static void main(String[] asd){
String sourcestring = "source string to match with pattern";
Pattern re = Pattern.compile("<a(?=\\s|>)(?!(?:[^>=]|=(['\"])(?:(?!\\1).)*\\1)*?\\shref=['\"])[^>]*>.*?<\\/a>
",Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
Matcher m = re.matcher(sourcestring);
int mIdx = 0;
while (m.find()){
for( int groupIdx = 0; groupIdx < m.groupCount()+1; groupIdx++ ){
System.out.println( "[" + mIdx + "][" + groupIdx + "] = " + m.group(groupIdx));
}
mIdx++;
}
}
}

匹配

$matches Array:
(
[0] => Array
(
[0] => <a bogus='href=""' class="aClass" target="_blank">link2</a>
)

[1] => Array
(
[0] =>
)

)

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com