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

时间:2008-12-15 17:40:18

标签: javascript regex anchor

我在javascript变量中有一段名为'input_content'的文本,该文本包含多个锚标记/链接。我想匹配所有锚标签并提取锚文本和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),但我对这一点感到困惑。谢谢你的帮助!

6 个答案:

答案 0 :(得分:42)

var matches = [];

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

这假设您的锚点始终采用<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部分
  • arguments [3]是
  • 中的文字

我们将使用hack将这三个参数作为新数组推送到我们的主matches数组中。 arguments内置变量不是真正的JavaScript数组,因此我们必须在其上应用split Array方法来提取我们想要的项目:

Array.prototype.slice.call(arguments, 1, 4)

这将从索引1开始的arguments和索引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"));

给出:

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

答案 1 :(得分:9)

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

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

答案 2 :(得分:6)

我认为乔尔有权利 - 因为有很多可能需要考虑的因素,正则表达式因为标记效果不佳而臭名昭着。锚标签还有其他属性吗?他们的订单是什么?分离的空格总是一个空格吗?看到您已经拥有浏览器的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;
}

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

答案 3 :(得分:2)

我认为JQuery是您最好的选择。这不是最好的剧本,我相信其他人可以提供更好的东西。但这会创建一个正是您正在寻找的阵列。

<script type="text/javascript">
    // From http://brandonaaron.net Thanks!
    jQuery.fn.outerHTML = function() {
        return $('<div>').append( this.eq(0).clone() ).html();
    };    

    var items = new Array();
    var i = 0;

    $(document).ready(function(){
        $("a").each(function(){
            items[i] = {el:$(this).outerHTML(),href:this.href,text:this.text};
            i++;      
        });
    });

    function showItems(){
        alert(items);
    }

</script>

答案 4 :(得分:1)

为了搜索者的利益:我创建了一些可以在锚标记中使用其他属性的东西。对于那些不熟悉正则表达式的人来说,美元(1美元等)值是正则表达式组匹配。

var text = 'This is my <a target="_blank" href="www.google.co.uk">link</a> Text';
var urlPattern = /([^+>]*)[^<]*(<a [^>]*(href="([^>^\"]*)")[^>]*>)([^<]+)(<\/a>)/gi;
var output = text.replace(urlPattern, "$1___$2___$3___$4___$5___$6");
alert(output);

查看工作jsFiddleregex101

或者,您可以从这些组中获取信息:

var returnText = text.replace(urlPattern, function(fullText, beforeLink, anchorContent, href, lnkUrl, linkText, endAnchor){
                    return "The bits you want e.g. linkText";
                });

答案 5 :(得分:1)

提取网址:

var pattern = /.href=" ;(.)"。* /; var url = string.replace(pattern,&#39; $ 1&#39;);

演示:

//var string = '<a id="btn" target="_blank" class="button" href="https://yourdomainame.com:4089?param=751&amp;2ndparam=2345">Buy Now</a>;'
//uncomment the above as an example of link.outerHTML

var string = link.outerHTML
var pattern = /.*href="(.*)".*/;
var href = string.replace(pattern,'$1');
alert(href)

对于&#34;锚文本&#34;,为什么不使用: link.innerHtml