Javascript拆分文本和正则表达式
我在debian下使用firefox,我不理解javascript的组成:Javascript拆分文本和正则表达式,javascript,regex,Javascript,Regex,我在debian下使用firefox,我不理解javascript的组成: var testRegex = /yolo .+ .+/gu; let test = `yolo 2 abc yolo 2 abc`; test = test.split('\n'); for (let t=0; t < test.length; t++) { console.log(test[t], testRegex.exec(test[t])); } var testRegex=/yolo.++
var testRegex = /yolo .+ .+/gu;
let test = `yolo 2 abc
yolo 2 abc`;
test = test.split('\n');
for (let t=0; t < test.length; t++)
{
console.log(test[t], testRegex.exec(test[t]));
}
var testRegex=/yolo.++/gu;
let test=`yolo 2 abc
yolo2abc`;
test=test.split('\n');
for(设t=0;t
它会发回:
更奇怪的是:
for (let t=0; t < test.length; t++)
{
console.log(test[t], testRegex.exec(test[t]), test[t].match(testRegex));
}
for(让t=0;t
发回:
我认为这不可能是编码问题,也不可能是我的代码造成的
我能做什么?这实际上是预期的行为,信不信由你。JavaScript正则表达式上的
exec()
方法是有状态的,可以在循环中调用。每次后续执行都将返回字符串中的下一个匹配项,直到没有找到进一步的匹配项为止,此时将返回null
为了在第一个示例中强调这一点,让我们快速简化代码,并显示每个变量中的值
let testRegex = /yolo .+ .+/gu;
let test = [
"yolo 2 abc",
"yolo 2 abc"
]
这导致对testRegex.exec
的调用如下所示:
testRegex.exec("yolo 2 abc") // => Array ["yolo 2 abc"]
testRegex.exec("yolo 2 abc") // => null
您可以找到这方面的官方文档,其中说明:
如果正则表达式使用“g”标志,则可以多次使用exec()
方法来查找同一字符串中的连续匹配项。执行此操作时,搜索从正则表达式的lastIndex
属性指定的str
子字符串开始(test()
也将推进lastIndex
属性)。请注意,lastIndex
属性在搜索其他字符串时不会重置,它将从其现有的lastIndex
开始搜索
您提供的第二个示例没有遇到此问题的原因是,match()
函数在内部将lastIndex
属性重置为0,重置搜索位置,并导致从正则表达式开始第二次调用exec()
搜索
回到最初的示例,您可以按如下方式修改它,您将看到预期的行为:
var testRegex = /yolo .+ .+/gu;
let test = `yolo 2 abc
yolo 2 abc`;
test = test.split('\n');
for (let t=0; t < test.length; t++)
{
console.log(test[t], testRegex.exec(test[t]));
testRegex.lastIndex = 0;
}
var testRegex=/yolo.++/gu;
let test=`yolo 2 abc
yolo2abc`;
test=test.split('\n');
for(设t=0;t
信不信由你,这实际上是意料之中的行为。JavaScript正则表达式上的exec()
方法是有状态的,可以在循环中调用。每次后续执行都将返回字符串中的下一个匹配项,直到没有找到进一步的匹配项为止,此时将返回null
为了在第一个示例中强调这一点,让我们快速简化代码,并显示每个变量中的值
let testRegex = /yolo .+ .+/gu;
let test = [
"yolo 2 abc",
"yolo 2 abc"
]
这导致对testRegex.exec
的调用如下所示:
testRegex.exec("yolo 2 abc") // => Array ["yolo 2 abc"]
testRegex.exec("yolo 2 abc") // => null
您可以找到这方面的官方文档,其中说明:
如果正则表达式使用“g”标志,则可以多次使用exec()
方法来查找同一字符串中的连续匹配项。执行此操作时,搜索从正则表达式的lastIndex
属性指定的str
子字符串开始(test()
也将推进lastIndex
属性)。请注意,lastIndex
属性在搜索其他字符串时不会重置,它将从其现有的lastIndex
开始搜索
您提供的第二个示例没有遇到此问题的原因是,match()
函数在内部将lastIndex
属性重置为0,重置搜索位置,并导致从正则表达式开始第二次调用exec()
搜索
回到最初的示例,您可以按如下方式修改它,您将看到预期的行为:
var testRegex = /yolo .+ .+/gu;
let test = `yolo 2 abc
yolo 2 abc`;
test = test.split('\n');
for (let t=0; t < test.length; t++)
{
console.log(test[t], testRegex.exec(test[t]));
testRegex.lastIndex = 0;
}
var testRegex=/yolo.++/gu;
let test=`yolo 2 abc
yolo2abc`;
test=test.split('\n');
for(设t=0;t
一个“全局”正则表达式是有状态的。它从上一个匹配结束后的位置开始搜索。您正在搜索两个不同的字符串,但正则表达式不知道这一点,因此它仍然开始第二次搜索字符串中的多个索引。事实上,去掉g标志可以使其工作,但我不理解为什么它可能是问题的根源。这里的关键是JavaScript对象在设置或标志时是有状态的,请参阅。@TheDelta:将以下内容添加到日志中:testRegex.lastIndex
。这显示了它用作起点的索引。在第二次搜索中,它的起点将远远超过预期匹配的起点。@ziggywiggy哦。。那么好:)我认为搜索是从搜索的每个新字符串的开头开始的。“全局”正则表达式是有状态的。它从上一个匹配结束后的位置开始搜索。您正在搜索两个不同的字符串,但正则表达式不知道这一点,因此它仍然开始第二次搜索字符串中的多个索引。事实上,去掉g标志可以使其工作,但我不理解为什么它可能是问题的根源。这里的关键是JavaScript对象在设置或标志时是有状态的,请参阅。@TheDelta:将以下内容添加到日志中:testRegex.lastIndex
。这显示了它用作起点的索引。在第二次搜索中,它的起点将远远超过预期匹配的起点。@ziggywiggy哦。。然后确定:)我认为搜索是从搜索的每个新字符串的开头开始进行的。