我在一个名为'input_content'的javascript变量中有一段文本,该文本包含多个锚标记/链接.我想匹配所有锚标签并提取锚文本和URL,并将其放入类似(或类似)的数组中:
Array ( [0] => Array ( [0] => Yahoo [1] => http://yahoo.com [2] => Yahoo ) [1] => Array ( [0] => Google [1] => http://google.com [2] => Google ) )
我对它采取了一个裂缝(http://pastie.org/339755),但我超越了这一点.谢谢您的帮助!
var matches = []; input_content.replace(/[^<]*(([^<]+)<\/a>)/g, function () { matches.push(Array.prototype.slice.call(arguments, 1, 4)) });
这假定您的锚点将始终处于表单中,...
即如果存在任何其他属性,则它将不起作用(例如,target
).可以改进正则表达式以适应这种情况.
要打破正则表达式:
/ -> start regular expression [^<]* -> skip all characters until the first < ( -> start capturing first 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)
这将从arguments
索引1开始并在索引4处结束(不包括)提取项目.
var input_content = "blah \ Yahoo \ blah \ Google \ blah"; var matches = []; input_content.replace(/[^<]*(([^<]+)<\/a>)/g, function () { matches.push(Array.prototype.slice.call(arguments, 1, 4)); }); alert(matches.join("\n"));
得到:
Yahoo,http://yahoo.com,Yahoo Google,http://google.com,Google
由于你可能在网络浏览器中运行javascript,因此正则表达式似乎是一个坏主意.如果段落首先来自页面,请获取容器的句柄,调用.getElementsByTagName()
以获取锚点,然后以这种方式提取所需的值.
如果那是不可能的,那么创建一个新的html元素对象,将文本分配给它的.innerHTML属性,然后调用.getElementsByTagName()
.
我认为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(['' + text + '', href, text]; } return list; }
无论链接如何存储,这都将返回与您描述的数组类似的数组.请注意,您可以通过将参数名称更改为"container"并删除前两行来更改函数以使用传递的元素而不是文本.textContent/innerText属性获取为链接显示的文本,删除任何标记(粗体/斜体/字体/ ...).如果要保留标记,可以用.innerHTML替换.textContent并删除内部if()语句.