【问题标题】:Regular expression returning some awkward value正则表达式返回一些尴尬的值
【发布时间】:2012-06-08 17:24:51
【问题描述】:

我有以下 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 文档中找到所有标签。所以理想情况下它应该返回&lt;a id="test"&gt;hi&lt;/a&gt;, &lt;p&gt;&lt;/p&gt;

但它目前返回&lt;a id="test"&gt;hi&lt;/a&gt;, a ,hi

为什么会这样?

还有一个问题,str.match(patt)patt.exec(str)有什么区别,哪个更好用?

【问题讨论】:

  • 为什么不使用 dom 解析器而不是正则表达式?
  • 嗯,jquery 是一个非常好的 dom 解析器,除了其他的东西
  • 但是我这里需要的是 html 解析器而不是 dom 解析器。我正在从文件中读取 html 输入
  • dom 代表“文档对象模型”,它是浏览器对 xml/html 字符串代码的内部表示。 jQuery 也可以处理:$('your valid html string here...').find('a');
  • 使用 jQuery,您的查询将只是 $(htmlString).find("*");

标签: javascript html-parsing html


【解决方案1】:
var patt=/[<](\S+).*>(.*)<\/\1>/g;

尝试指定global 修饰符(否则它将在找到的第一个匹配项处停止)。

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

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

【讨论】:

    【解决方案2】:

    试试这个:

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

    额外的ahi 存在是因为您将它们作为捕获组。这个只会返回标签。它的一个缺陷是它会匹配&lt;begin&gt;dfgdf&lt;/diffEnd&gt;

    【讨论】:

    【解决方案3】:

    您需要将全局修饰符 g 附加到您的正则表达式:/[&lt;](\S+).*&gt;(.*)&lt;\/\1&gt;/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获取整个匹配项的列表,而不是与这些匹配项匹配的模式。

    // 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 而不是数组。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      • 2023-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多