javascript正则表达式从锚标记中提取锚文本和URL

chi*_*ior 14 javascript regex anchor

我在一个名为'input_content'的javascript变量中有一段文本,该文本包含多个锚标记/链接.我想匹配所有锚标签并提取锚文本和URL,并将其放入类似(或类似)的数组中:

Array
(
    [0] => Array
        (
            [0] => <a href="http://yahoo.com">Yahoo</a>
            [1] => http://yahoo.com
            [2] => Yahoo
        )
    [1] => Array
        (
            [0] => <a href="http://google.com">Google</a>
            [1] => http://google.com
            [2] => Google
        )
)

我对它采取了一个裂缝(http://pastie.org/339755),但我超越了这一点.谢谢您的帮助!

Ate*_*ral 45

var matches = [];

input_content.replace(/[^<]*(<a href="([^"]+)">([^<]+)<\/a>)/g, function () {
    matches.push(Array.prototype.slice.call(arguments, 1, 4))
});
Run Code Online (Sandbox Code Playgroud)

这假定您的锚点将始终处于表单中,<a href="...">...</a>即如果存在任何其他属性,则它将不起作用(例如,target).可以改进正则表达式以适应这种情况.

要打破正则表达式:

/ -> start regular expression
  [^<]* -> skip all characters until the first <
  ( -> start capturing first token
    <a href=" -> capture first bit of anchor
    ( -> start capturing second token
        [^"]+ -> capture all characters until a "
    ) -> end capturing second token
    "> -> capture more of the anchor
    ( -> start capturing third token
        [^<]+ -> capture all characters until a <
    ) -> end capturing third token
    <\/a> -> capture last bit of anchor
  ) -> end capturing first token
/g -> end regular expression, add global flag to match all anchors in string

每次调用我们的匿名函数都会收到三个标记作为第二,第三和第四个参数,即参数[1],参数[2],参数[3]:

  • arguments [1]是整个锚点
  • 参数[2]是href部分
  • 参数[3]是里面的文字

我们将使用hack将这三个参数作为一个新数组推送到我们的主matches数组中.该arguments内置变量不是一个真正的JavaScript数组,所以我们必须要应用split它阵列的方法来提取我们想要的物品:

Array.prototype.slice.call(arguments, 1, 4)
Run Code Online (Sandbox Code Playgroud)

这将从arguments索引1开始并在索引4处结束(不包括)提取项目.

var input_content = "blah \
    <a href=\"http://yahoo.com\">Yahoo</a> \
    blah \
    <a href=\"http://google.com\">Google</a> \
    blah";

var matches = [];

input_content.replace(/[^<]*(<a href="([^"]+)">([^<]+)<\/a>)/g, function () {
    matches.push(Array.prototype.slice.call(arguments, 1, 4));
});

alert(matches.join("\n"));
Run Code Online (Sandbox Code Playgroud)

得到:

<a href="http://yahoo.com">Yahoo</a>,http://yahoo.com,Yahoo
<a href="http://google.com">Google</a>,http://google.com,Google

  • 不一定同意正则表达式最适合这个,但是要花时间去做出好的解释以及一旦你有匹配就做了什么. (4认同)

Joe*_*orn 10

由于你可能在网络浏览器中运行javascript,因此正则表达式似乎是一个坏主意.如果段落首先来自页面,请获取容器的句柄,调用.getElementsByTagName()以获取锚点,然后以这种方式提取所需的值.

如果那是不可能的,那么创建一个新的html元素对象,将文本分配给它的.innerHTML属性,然后调用.getElementsByTagName().


Ben*_*ank 7

我认为Joel拥有它的权利 - 正则表达式因为标记效果不佳而臭名昭着,因为有太多的可能性需要考虑.锚标签还有其他属性吗?他们的订单是什么?分离的空格总是一个空格吗?看到您已经拥有浏览器的HTML 解析器,最好将其用于工作.

function getLinks(html) {
    var container = document.createElement("p");
    container.innerHTML = html;

    var anchors = container.getElementsByTagName("a");
    var list = [];

    for (var i = 0; i < anchors.length; i++) {
        var href = anchors[i].href;
        var text = anchors[i].textContent;

        if (text === undefined) text = anchors[i].innerText;

        list.push(['<a href="' + href + '">' + text + '</a>', href, text];
    }

    return list;
}
Run Code Online (Sandbox Code Playgroud)

无论链接如何存储,这都将返回与您描述的数组类似的数组.请注意,您可以通过将参数名称更改为"container"并删除前两行来更改函数以使用传递的元素而不是文本.textContent/innerText属性获取为链接显示的文本,删除任何标记(粗体/斜体/字体/ ...).如果要保留标记,可以用.innerHTML替换.textContent并删除内部if()语句.