【问题标题】:javascript regex for links and links class链接和链接类的 javascript 正则表达式
【发布时间】:2014-06-13 17:08:15
【问题描述】:

我需要使用正则表达式从 javascript 中的文本中收集所有链接,将 href 的实际内容和链接的文本分开。所以如果链接是

<a href="someplace/topics/us/john.htm" class="r_lapi">John Dow</a>

我想收集href和“John Dow”的内容。

链接中有 class="r_lapi" 可以识别我正在寻找的链接。 我现在拥有的是:

     var link_regex = new RegExp("/<a[^]*</a>/");
     var match = content.match(link_regex, 'i');
     console.log("match =", match );

这绝对什么都不做。非常感谢任何帮助。

【问题讨论】:

  • 为什么要使用正则表达式?为什么不使用 DOM?您是在浏览器之外执行此操作吗?

标签: javascript regex


【解决方案1】:

如果你可以使用 DOM(你说过你想要正则表达式,但是......)

var i;
var links = document.querySelectorAll("a.r_lapi");
for (i = 0; i < links.length; ++i) {
    // use `links[i].innerHTML` here
}

您在评论中说您正在尝试使用正则表达式执行此操作,因为您通过 ajax 接收链接 HTML(可能与一堆其他内容混合)。您可以使用浏览器对其进行解析,然后在解析结果中查找链接,无需将 HTML 添加到您的文档中,使用断开连接的元素:

var div, links, i;

// Create an element; note we don't append it anywhere
div = document.createElement('div');

// Fill it in with the HTML
div.innerHTML = text;

// Find relevant links (same as the earlier example)
links = div.querySelectorAll("a.r_lapi");
for (i = 0; i < links.length; ++i) {
    // use `links[i].innerHTML` here
}

Live Example,使用通过 ajax 返回的文本:

<a href="someplace/topics/us/john.htm" class="r_lapi">John Dow</a>
<a href="foo">Don't pick me</a>
<a href="blahblahblah" class="r_lapi">Jane Bloggs</a>

这里唯一真正的“陷阱”是,如果 HTML 包含图像标签,浏览器将开始下载这些图像(即使它们不会在任何地方显示)。即使您使用文档片段也是如此,这也是我没有在上面打扰的部分原因。 (文本中的script 标记不是问题,当您使用innerHTML 时它们不会被执行,但要注意它们由诸如jQuery 的html 函数之类的东西执行的。)

或者,如果数据以其他形式(如 JSON)返回给您,其中包含 HTML,解析 JSON(或其他),然后通过 div 一次运行每个 HTML 片段:

function handleLinks(data) {
  var div, links, htmlIndex, linkIndex;

  div = document.createElement('div');
  for (htmlIndex = 0; htmlIndex < data.htmlList.length; ++htmlIndex) {
    div.innerHTML = data.htmlList[htmlIndex];
    links = div.querySelectorAll("a.r_lapi");
    for (linkIndex = 0; linkIndex < links.length; ++linkIndex) {
      // Use `links[linkIndex].innerHTML` here
    }
  }
}

Live Example,使用通过 ajax 返回的 JSON:

{
    "htmlList": [
        "blah blah <a href=\"someplace/topics/us/john.htm\" class=\"r_lapi\">John Dow</a> blah blah",
        "<a href=\"foo\">Don't pick me</a>",
        "Two in this one <a href=\"blahblahblah\" class=\"r_lapi\">Jane Bloggs</a> and <a href=\"blahblahblah\" class=\"r_lapi\">Trevor Bloggs</a>"
    ]
}

如果你真的需要使用正则表达式:

请注意,您不能使用 JavaScript 中的正则表达式可靠地做到这一点;你需要一个解析器。

您可以关闭几个假设。

 var link_regex = /<a(?:>|\s[^>]*>)(.*?)<\/a>/i;
 var match = content.match(link_regex);
 if (match) {
     // Use match[1], which contains it
 }

Live illustration

寻找这个:

  1. 文字文本&lt;a
  2. 要么紧跟一个&gt;,要么至少一个空白字符后跟任意数量的不是&gt;的字符,再跟一个&gt;
  3. 任意数量的字符,最小匹配
  4. 文字文本&lt;/a&gt;

第 3 步中的“最小匹配”是,如果我们有 &lt;a&gt;first&lt;/a&gt;&lt;a&gt;second&lt;/a&gt;,我们不会得到比我们想要的更多。

我没有尝试按班级限制正则表达式,我将把它作为练习留给读者。 :-)

不过,这又是一个坏主意。相反,请使用 DOM(如果您在浏览器之外执行此操作,则可以使用大量 DOM 实现)。

上面所做的主要假设之一是锚的属性值中永远不存在&gt;字符(例如,属性值中的&lt;a href="..." data-something="I have a &gt; in me"&gt;John Dow&gt;&lt;/a&gt;). It's perfectly valid to have a>`,因此该假设无效。

【讨论】:

  • 非常感谢您的帮助!我得到了正则表达式的工作。我希望链接通过 ajax 返回,否则我肯定会使用 querySelectorAll 的解决方案。此外,我的链接将与特定来源相关,具有可预测的格式,因此我不希望它们中有特殊字符。我现在准备好了!
  • @lw0:很高兴有帮助!顺便说一句,您仍然不必对通过 ajax 返回的数据使用正则表达式。我添加了几个示例来说明如何做到这一点。
【解决方案2】:

如果你在浏览器中,你真的应该使用原生 DOM。

如果不是,假设 href 不包含像 &gt;" 这样的奇怪字符,您可以使用以下正则表达式:

var matches = link.match(/^<a\s+[^>]*href="([^"]+)"[^>]*>([^<]*)<\/a>$/);
matches[1] == "someplace/topics/us/john.htm";
matches[2] == "John Dow";

请注意,这将在某些链接上失败,例如

  • &lt;a href="&gt;"&gt;test&lt;/a&gt;
  • &lt;a href="test"&gt;John &lt;b&gt;Dow&lt;/b&gt;&lt;/a&gt;

要获得完整的解决方案,请使用 HTML 解析器。

【讨论】:

  • 非常感谢您的回复。出于某种原因,你的表达方式对我不起作用。我满足于以下正则表达式,它让我非常接近我需要的内容: content.match(/]*>([^/g);
猜你喜欢
  • 2010-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-12
  • 1970-01-01
相关资源
最近更新 更多