【问题标题】:Javascript Match and RegExp Issue -- Strange BehaviorJavascript 匹配和正则表达式问题——奇怪的行为
【发布时间】:2009-07-16 11:28:58
【问题描述】:

我一直在尝试使用一个简单的 jQuery 操作来动态匹配和存储页面上的所有锚标记及其文本。但我发现了一个奇怪的行为。当您使用 match() 或 exec() 时,如果您将 needle 指定为单独的 RegExp 对象或模式变量,那么您的查询只会匹配大海捞针中的几十个实例中的一个。

如果你这样指定模式

match(/needle/gi) 

然后它匹配针的每个实例。

这是我的代码。

您甚至可以在此页面上启动 Firebug 并尝试此代码。

var a = {'text':'','parent':[]}; 

$("a").each(function(i,n) {

    var module = $.trim($(n).text());
    a.text += module.toLowerCase() + ',' + i + ','; 

    a.parent.push($(n).parent().parent()); 

});

var stringLowerCase = 'b';

var regex = new RegExp(stringLowerCase, "gi");
//console.log(a.text);
console.log("regex 1: ", regex.exec(a.text));

var regex2 = "/" + stringLowerCase + "/";
console.log("regex 2: ", a.text.match(regex2));

console.log("regex 3: ", a.text.match(/b/gi));

对我来说它正在回归:

regex 1:  ["b"]
regex 2: null
regex 3: ["b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b"]

谁能解释这种行为的根源?

编辑:我忘了提到,对于 regex1,是否为全局和不区分大小写的匹配添加标志“gi”没有任何区别。它仍然只返回一个匹配项。

EDIT2:解决了我自己的问题。我仍然不知道为什么一个 regex1 只匹配一个实例,但我设法使用 match() 和 regex1 匹配所有实例。

所以..this 匹配所有动态!

var regex = new RegExp(stringLowerCase, "gi");
console.log("regex 2: ", a.text.match(regex));

【问题讨论】:

  • a.text的内容是什么
  • a 只是一个包含两个元素的对象。我在代码的顶部定义了它。它的上下文可能是文档对象。

标签: javascript jquery regex


【解决方案1】:

这根本不是不寻常的行为。在正则表达式 1 中,您只检查它的 1 个实例,而在正则表达式 3 中,您告诉它使用 /gi 参数返回该项目的所有实例。

在 Regex 2 中,您假设 "/b/" === /b/ 但事实并非如此。 “/b/”!== /b/。 “/b/”是一个正在搜索的字符串,所以如果你的字符串中有“/b/”,那么它会返回,而/b/意味着它需要在斜杠之间搜索,所以你可以有“abc”,它会返回“b”

希望对你有帮助。

编辑:

进一步研究,exec 方法返回它找到的第一个匹配项,而不是它找到的所有匹配项。

编辑:

var myRe = /ab*/g;
var str = "abbcdefabh";
var myArray;
while ((myArray = myRe.exec(str)) != null)
{
  var msg = "Found " + myArray[0] + ".  ";
  msg += "Next match starts at " + myRe.lastIndex;
  console.log(msg);
}

再次查看它肯定会返回它找到的第一个实例。如果你循环通过它,那么会返回更多。

为什么会这样?我不知道...我的 JavaScript 功夫显然不足以回答那部分

【讨论】:

  • 我应该说清楚的。对于 regx1,当我在 RegExp 对象的定义中添加“gi”时,它并没有什么不同。自己试试吧。
  • 你知道为什么会这样吗?我确实在 RegExp 定义中添加了 g 标志,所以它应该进行全局匹配,对吧?
【解决方案2】:

正则表达式 2 返回 null 的原因是您将“/b/”作为模式参数传递,而“b”实际上是唯一真正成为模式一部分的东西。斜杠是正则表达式的简写,就像 [ ] 是数组一样。因此,如果您将其替换为新的正则表达式(“b”),您将得到一个匹配项,但只有一个匹配项,因为您在该示例中省略了“global+ignorecase”标志。要获得 #2 和 #3 相同的结果,请进行相应修改:

var regex2 = stringLowerCase;
console.log("regex 2: ", a.text.match(regex2, "gi"));
console.log("regex 3: ", a.text.match(/b/gi));

【讨论】:

    【解决方案3】:

    regex2 是一个字符串,而不是 RegExp,我在使用这种语法时也遇到了麻烦,虽然我不太确定这种行为。

    编辑:记住:对于 regex2,JS 寻找“/b/”作为针,而不是“b”。

    【讨论】:

    • 但是 regex1 呢?那应该行得通。你最终是如何解决你的问题的?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多