【问题标题】:Regex <img > Tag parsing with src, width, height正则表达式 <img > 标签解析与 src、宽度、高度
【发布时间】:2016-08-27 00:18:54
【问题描述】:

您可能会对这句话做出反应,即使用正则表达式进行 HTML 解析是一个完全坏主意,例如遵循 this,您是对的。

但在我的例子中,下面的 html 节点是由我们自己的服务器创建的,所以我们知道它总是看起来像这样,因为正则表达式将在 移动 android 库中,所以我不知道不想使用 Jsoup 之类的库。

我要解析的内容&lt;img src="myurl.jpg" width="12" height="32"&gt;

应该解析什么

  • 匹配一个常规的img标签,并分组src属性值:&lt;img[^&gt;]+src\\s*=\\s*['\"]([^'\"]+)['\"][^&gt;]*&gt;
  • 宽度和高度属性值:(width|height)\s*=\s*['"]([^'"]*)['"]*

所以第一个正则表达式将有一个带有 img url 的 #1 组,第二个正则表达式将有两个匹配其值的子组。

如何合并两者?

期望的输出:

  • 图片网址
  • 宽度值
  • 高度值

【问题讨论】:

  • 你想要 this 吗?
  • "下面的 html 节点是由我们自己的服务器创建的" 所以将服务器改为返回 JSON。服务器始终是用来完成繁重工作的,而不是移动设备。
  • @rock321987:你的更简单,也许对于 OP 来说已经足够了。另外,我不确定需要什么确切的输出。
  • 我已经更新了帖子,我认为@rock321987 已经得到了答案

标签: java android html regex


【解决方案1】:

要将任何img 标记与srcheightwidth 属性匹配,这些属性可以以任何顺序出现并且实际上是可选的,您可以使用

"(<img\\b|(?!^)\\G)[^>]*?\\b(src|width|height)=([\"']?)([^>]*?)\\3"

查看regex demoIDEONE Java demo

String s = "<img height=\"132\" src=\"NEW_myurl.jpg\" width=\"112\"><link src=\"/test/test.css\"/><img src=\"myurl.jpg\" width=\"12\" height=\"32\">";
Pattern pattern = Pattern.compile("(<img\\b|(?!^)\\G)[^>]*?\\b(src|width|height)=([\"']?)([^\"]*)\\3");
Matcher matcher = pattern.matcher(s);
while (matcher.find()){
    if (!matcher.group(1).isEmpty()) { // We have a new IMG tag
        System.out.println("\n--- NEW MATCH ---");  
    }
    System.out.println(matcher.group(2) + ": " + matcher.group(4));
} 

正则表达式详细信息:

  • (&lt;img\\b|(?!^)\\G) - 与&lt;img&gt;标签匹配的初始边界开始或上一次成功匹配的结束
  • [^&gt;]*? - 匹配我们不感兴趣的任何可选属性(除&gt; 之外的0+ 个字符,以便留在标签内) -\\b(src|width|height)= - 一个完整的单词src=width=height=
  • ([\"']?) - 检查属性值分隔符的技术第三组
  • ([^&gt;]*?) - 包含属性值的第 4 组(除 &gt; 之外的 0+ 个字符,在第一个之前尽可能少
  • \\3 - 与第 3 组匹配的属性值分隔符(注意如果分隔符可能为空,请在模式末尾添加 (?=\\s|/?&gt;)

逻辑:

  • 匹配img标签的开头
  • 然后,匹配里面的所有内容,但只捕获我们需要的属性
  • 由于我们将有多个匹配项,而不是组,我们需要为每个新的img 标记找到一个边界。这是通过检查第一组是否不为空来完成的 (if (!matcher.group(1).isEmpty()))
  • 剩下要做的就是添加一个保持匹配的列表。

【讨论】:

    【解决方案2】:

    如果你想将两者结合起来,这里就是答案。

    <img\s+src="([^"]+)"\s+width="([^"]+)"\s+height="([^"]+)"
    

    我测试的样本

    <img src="rakesh.jpg" width="25" height="45">
    

    试试这个

    【讨论】:

      【解决方案3】:

      你可能想要这个:

      "(?i)(src|width|height)=\"(.*?)\""
      


      更新:

      我误解了你的问题,你需要这样的东西:

      "(?i)<img\\s+src=\"(.*?)\"\\s+width=\"(.*?)\"\\s+height=\"(.*?)\">"
      

      Regex101 Demo


      更新 2

      下面的正则表达式将按任意顺序捕获img 标签属性:

      "(?i)(?><img\\s+)src=\"(.*?)\"|width=\"(.*?)\"|height=\"(.*?)\">"  
      

      Regex101 Demo v2

      【讨论】:

      • 这将匹配 HTML 代码中的任何 srcheightwidth 属性。
      • 是的,确实如此,所以 OP 知道哪个值匹配,例如 width vs height,标签的顺序无关紧要,它可以是不同的 @987654332 @ 带有重新排序属性的标签,它仍然有效。
      • 但它不会验证 标签
      • 如果属性可以以不同的顺序出现,我的正则表达式是正确的解决方案。
      • @PedroLobito:阅读整个问题。但是,它并没有帮助我理解所有这些。重点是应该只匹配img标签。