正则表达式返回一些尴尬的值

时间:2012-06-04 16:26:27

标签: javascript html-parsing html

我有以下javascript代码:

<script type="text/javascript"> //javascript starts

 var patt=/[<](\S+).*>(.*)<\/\1>/;
 var str='<a id="test">hi</a> <p></p>';

 alert(str.match(patt));
 alert(patt.exec(str));

</script>

希望查找html文档中的所有标记。理想情况下,它应该返回<a id="test">hi</a>, <p></p>

但它目前返回<a id="test">hi</a>, a ,hi

为什么会发生这种情况?

另一个问题, str.match(patt)patt.exec(str)之间的区别是什么,哪个更好?

3 个答案:

答案 0 :(得分:2)

var patt=/[<](\S+).*>(.*)<\/\1>/g;

尝试指定global修饰符(或者它会在找到的第一个匹配项时停止。)

关于你的第二个问题MDN是一个很好的资源:
来自https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/match

  

如果正则表达式不包含g标志,则返回与regexp.exec(字符串)相同的结果。如果正则表达式包含g标志,则该方法返回包含所有匹配项的数组。如果没有匹配项,则该方法返回null。

答案 1 :(得分:1)

您需要将全局修饰符g附加到正则表达式:/[<](\S+).*>(.*)<\/\1>/g

  • 如果您不使用g全局修饰符,matchexec将返回一个包含字符串中第一个匹配项的数组作为第一个元素,然后匹配中的任何括号匹配模式作为后续数组元素。

  • 如果您使用g修饰符,matchexec将获得字符串中的所有匹配项。 match将它们作为数组返回,exec将为每个匹配返回一个数组(匹配模式,因为它没有g)但多次调用每个exec都会返回一个不同的匹配,直到所有匹配报告为止(详见下文)。

一般情况下,我建议match超过exec,因为exec依赖于正则表达式维护状态(具体来说,lastIndex,字符串所在的字符串索引比赛应该恢复)。如果你想在多个字符串上使用正则表达式,我发现这是有害的:

var reg = /\w/g;
reg.exec("foo"); // ["f"]
reg.exec("foo"); // ["o"]
reg.exec("bar"); // ["r"] -- does not start at the beginning of the string

将其与match行为进行比较:

var reg = /\w/g;
"foo".match(reg); // ["f", "o", "o"]
"bar".match(reg); // ["b", "a", "r"]
// we can now use the arrays to get individual matches

但是,如果您需要在全局搜索中为每个匹配获取带括号的匹配模式,则必须使用exec,因为match的全局应用1}}只获取整个匹配的列表,而不是匹配那些匹配的模式。

// the ending digit is a match pattern
var reg = /\w(\d)/g;

// match only gets list of whole matches
"d1b4h7".match(reg); // ["d1","b4","h7"] 

// exec gets the match and the match pattern
reg.exec("d1b5h7"); // ["d1","1"]
reg.exec("d1b5h7"); // ["b4","4"]
reg.exec("d1b5h7"); // ["h7","7"]

总之,听起来您希望将match与全局修饰符一起使用,因为您不需要匹配模式信息。如果确实需要匹配模式信息,请使用循环重复调用exec来获取所有匹配项,直到exec返回null而不是数组。

答案 2 :(得分:0)

试试这个:

var patt=/<\S+[^>]*>[^<]*<\/\S+>/g;

额外的ahi就在那里,因为您将它们作为捕获组。这个只返回标签。它有一个缺陷就是匹配<begin>dfgdf</diffEnd>