18

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

大批
(
    [0] => 数组
        (
            [0] => <a href="http://yahoo.com">雅虎</a>
            [1] => http://yahoo.com
            [2] => 雅虎
        )
    [1] => 数组
        (
            [0] => <a href="http://google.com">谷歌</a>
            [1] => http://google.com
            [2] => 谷歌
        )
)

我已经破解了它(http://pastie.org/339755),但我很难过这一点。谢谢您的帮助!

4

6 回答 6

51
var matches = [];

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

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

分解正则表达式:

/ -> 开始正则表达式
  [^<]* -> 跳过所有字符,直到第一个 <
  ( -> 开始捕获第一个令牌
    <a href=" -> 捕获第一个锚点
    ( -> 开始捕获第二个令牌
        [^"]+ -> 捕获所有字符直到 "
    ) -> 结束捕获第二个令牌
    "> -> 捕获更多的锚点
    ( -> 开始捕获第三个令牌
        [^<]+ -> 捕获所有字符,直到一个 <
    ) -> 结束捕获第三个标记
    </a> -> 捕获锚的最后一位
  ) -> 结束捕获第一个令牌
/g -> 结束正则表达式,添加全局标志以匹配字符串中的所有锚点

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

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

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

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

这将从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"));

给出:

<a href="http://yahoo.com">雅虎</a>,http://yahoo.com,雅虎
<a href="http://google.com">谷歌</a>,http://google.com,谷歌
于 2008-12-15T17:50:03.647 回答
10

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

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

于 2008-12-15T17:57:08.890 回答
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;
}

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

于 2008-12-15T18:12:34.723 回答
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>
于 2008-12-15T18:08:41.690 回答
2

为了搜索者的利益:我创建了一些可以与锚标记中的其他属性一起使用的东西。对于那些不熟悉 Regex 的人,美元($1 等)值是 regex 组匹配项。

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";
                });
于 2016-07-14T10:40:36.757 回答
2

提取网址:

var 模式 = /。href="(. )".*/; var url = string.replace(pattern,'$1');

演示:

//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)

对于“锚文本”,为什么不使用: link.innerHtml

于 2016-09-10T21:45:06.947 回答