console.log( html.match( /<a href="(.*?)">[^<]+<\/a>/g ));
而不仅仅返回网址:
http://google, http://yahoo.com
它将返回整个标记:
<a href="http://google.com">Google.com</a>, <a href="http://yahoo.com">Yahoo.com</a>
为什么会这样?
答案 0 :(得分:3)
您希望RegExp#exec
和循环访问匹配结果的1
索引处的元素,而不是String.match
。当有String.match
标志时,g
不返回捕获组,只是每个匹配的索引0
处的元素数组,这是整个匹配字符串。 (参见the spec的第15.5.4.10节。)
所以实质上:
var re, match, html;
re = /<a href="(.*?)">[^<]+<\/a>/g;
html = 'Testing <a href="http://yahoo.com">one two three</a> <a href="http://google.com">one two three</a> foo';
re.lastIndex = 0; // Work around literal bug in some implementations
for (match = re.exec(html); match; match = re.exec()) {
display(match[1]);
}
但这是使用正则表达式解析HTML。 这里有龙。
更新re龙,这是一个快速列出的东西,将击败这个正则表达式,从我的头顶:
a
和href
之间只有一个空格以外的任何内容,例如两个空格而不是一个,换行符,class='foo'
等。等等。href
属性周围使用单引号而不是双引号。href
属性周围的引号。 href
属性后也使用双引号的任何内容,例如:
<a href="http://google.com" class="foo">
这不是你的正则表达式,只是强调正则表达式无法在他们自己的上可靠地使用来解析HTML。它们可以构成解决方案的一部分,帮助您扫描令牌,但它们无法可靠地完成整个工作。
答案 1 :(得分:3)
虽然确实无法使用正则表达式可靠_ 解析 _ HTML,但这不是OP所要求的。
相反,OP需要一种从HTML文档中提取锚链接的方法,这种方法可以使用正则表达式轻松,令人钦佩地处理。
前一位回应者列出的四个问题:
只有数字3会对单个正则表达式解决方案带来严重问题,但也恰好是完全非标准的HTML,它永远不会出现在HTML文档中。 (请注意,如果您发现包含非分隔标记属性的HTML,则会有一个与它们匹配的正则表达式,但我认为它们不值得提取.YMMV - 您的里程可能会有所不同。)
要使用HTML中的正则表达式提取锚链接(hrefs),您可以使用此正则表达式(以注释形式):
< # a literal '<'
a # a literal 'a'
[^>]+? # one or more chars which are not '>' (non-greedy)
href= # literal 'href='
('|") # either a single or double-quote captured into group #1
([^\1]+?) # one or more chars that are not the group #1, captured into group #2
\1 # whatever capture group #1 matched
,没有评论,是:
<a[^>]+?href=('|")([^\1]+?)\1
(请注意,我们不需要匹配任何超过最终分隔符的内容,包括标记的其余部分,因为我们感兴趣的是锚链接。)
在JavaScript中,假设“source”包含您希望从中提取锚链接的HTML:
var source='<a href="double-quote test">\n'+
'<a href=\'single-quote test\'>\n'+
'<a class="foo" href="leading prop test">\n'+
'<a href="trailing prop test" class="foo">\n'+
'<a style="bar" link="baz" '+
'name="quux" '+
'href="multiple prop test" class="foo">\n'+
'<a class="foo"\n href="inline newline test"\n style="bar"\n />';
,当打印到控制台时,显示为:
<a href="double-quote test">
<a href='single-quote test'>
<a class="foo" href="leading prop test">
<a href="trailing prop test" class="foo">
<a style="bar" link="baz" name="quux" href="multiple prop test" class="foo">
<a class="foo"
href="inline newline test"
style="bar"
/>
你会写下以下内容:
var RE=new RegExp(/<a[^>]+?href=('|")([^\1]+?)\1/gi),
match;
while(match=RE.exec(source)) {
console.log(match[2]);
}
将以下行打印到控制台:
double-quote test
single-quote test
leading prop test
trailing prop test
multiple prop test
inline newline test
注意:
在nodejs v0.5.0-pre中测试过的代码,但应该在任何现代JavaScript下运行。
由于正则表达式使用捕获组#1来记录前导分隔引用,因此生成的链接将显示在捕获组#2中。
您可能希望使用以下方式验证匹配的存在,类型和长度:
if(match && typeof match === 'object' && match.length > 1) {
console.log(match[2]);
}
但它确实不应该是必要的,因为RegExp.exec()在失败时返回'null'。另请注意,正确的匹配类型是“对象”,而不是“数组”。