【问题标题】:RegEx for matching HTML tags with specific attributes [duplicate]用于匹配具有特定属性的 HTML 标记的正则表达式 [重复]
【发布时间】:2019-10-09 14:41:35
【问题描述】:

我有一个类似的字符串

<span title="use a <label>">Some Content</span>
<span title="use a <div>">Some Other Content</span>

我需要一个正则表达式来只获取 Some ContentSome Other Content 忽略标签,即使标签里面有另一个标签

【问题讨论】:

  • 如果你在 JS 中,parse it as a document fragment 并使用 DOM。正则表达式不适合这项工作。
  • 同意@Amy。你是抓取页面还是页面中的JS?
  • 无效的html是故意的吗?即在跨度开始标签上有一个结束标签标签。
  • Regex 是 absolutely 错误的工具。

标签: javascript html regex dom regex-group


【解决方案1】:

使用 document parser 和 DOM 方法来获取内容,而不是正则表达式。正则表达式绝对是这项工作的错误工具。即使你能得到一个有效的正则表达式,它也很难理解并且非常脆弱。下面的解决方案更健壮、更容易理解和更容易调试。

首先创建一个解析器并解析文档片段:

var parser = new DOMParser();
var doc = parser.parseFromString(
    '<span title="use a <label>">Some Content</label><span title="use a <div>">Some Other Content</label>',
    "text/html");

您可以通过检查doc.documentElement 来查看结果,这给了我们:

<html>
    <head></head>
    <body>
        <span title="use a <label>">
            Some Content
            <span title="use a <div>">
                Some Other Content
            </span>
        </span>
    </body>
</html>

因为你的标签没有正确关闭,它解析它很奇怪,但没关系。文本内容仍然是内容。

接下来,我们使用document walker 提取所有文本节点。你可以使用createTreeWalker创建一个新的walker,传入NodeFilter.SHOW_TEXT

var walker = doc.createTreeWalker(
    doc.documentElement,    // root
    NodeFilter.SHOW_TEXT,   // what to show
    null,                   // filter
    false);                 // reference expansion

然后我们可以遍历树并收集所有遍历的节点:

var node;
var textNodes = []; 
while (node = walker.nextNode()) {
    textNodes.push(node);
}

最后,我们得到了想要的数组:

var content = textNodes.map(x => x.textContent);

Content 是一个数组,其中包含所需的结果集 ["Some Content", "Some Other Content"]

【讨论】:

    【解决方案2】:

    也许你有什么想法。

    正则表达式:">(.*)

    Match 1
    Full match  26-42   ">Some Content</
    Group 1.    n/a Some Content
    Match 2
    Full match  73-95   ">Some Other Content</
    Group 1.    n/a Some Other Content
    

    https://regex101.com/r/6VArPY/1

    【讨论】:

      【解决方案3】:

      我们可能只使用一个简单的表达式并收集我们想要的文本内容,也许使用:

      ">(.+?)<\/
      

      我们的数据保存在(.+?)捕获组中。

      const regex = /">(.+?)<\//gm;
      const str = `<span title="use a <label>">Some Content</label>
      <span title="use a <div>">Some Other Content</label>`;
      let m;
      
      while ((m = regex.exec(str)) !== null) {
          // This is necessary to avoid infinite loops with zero-width matches
          if (m.index === regex.lastIndex) {
              regex.lastIndex++;
          }
          
          // The result can be accessed through the `m`-variable.
          m.forEach((match, groupIndex) => {
              console.log(`Found match, group ${groupIndex}: ${match}`);
          });
      }

      DEMO

      正则表达式

      如果不需要此表达式,可以在 regex101.com 中修改或更改。

      正则表达式电路

      jex.im 可视化正则表达式:

      【讨论】:

        猜你喜欢
        • 2012-02-18
        • 2013-06-16
        • 2015-03-15
        • 2019-04-12
        • 1970-01-01
        • 1970-01-01
        • 2019-09-25
        • 2023-03-24
        • 1970-01-01
        相关资源
        最近更新 更多