我已经解析了一个索引为idx
的字符串。我的下一个解析步骤使用Regexp。它需要匹配字符串的下一部分,即从位置idx
开始。我如何有效地做到这一点?
举例来说:
let myString = "<p>ONE</p><p>TWO</p>"
let idx
// some code not shown here parses the first paragraph
// and updates idx
idx = 10
// next parse step must continue from idx
let myRegex = /<p>[^<]*<\/p>/
let subbed = myString.substring(idx)
let result = myRegex.exec(subbed)
console.log(result) // "<p>TWO</p>", not "<p>ONE</p>"
字符串
但是myString.substring(idx)
似乎是一个相当昂贵的操作。
有没有这样的正则表达式操作:result = myRegex.execFromIndex(idx, myString);
?
一般来说,我想从不同的索引开始正则表达式匹配,这样我就可以排除字符串的一部分,避免已经解析过的匹配。所以一次可以是myString[0],另一次是myString[51],依此类推。
有没有一种方法可以有效地做到这一点?我正在解析成千上万的行,并希望以尽可能便宜的方式完成这一工作。
2条答案
按热度按时间wlwcrazw1#
JavaScript Regexp有一个
lastIndex
属性,它在Regexp.exec()
中用作占位符,包含最后一个匹配的索引,表明它知道下一步从哪里开始。因此,设置myRegex.lastIndex = 3
应该可以解决您的问题。它比substring方法更有效,因为它不需要创建额外的变量,并且设置lastIndex属性可能比执行子字符串操作更快。其他的一切都和你做的一样。
下面是一个测试,因为它表明设置
lastIndex
将产生与首先执行substring
相同的结果。个字符
jutyujz02#
使用
Regexp.exec
和lastIndex
y
org
flag创建Regexpy
标志,则匹配必须从指定的开始索引处开始g
标志,匹配可以发生在指定索引之后的任何位置lastIndex
属性设置为开始索引exec
我已经将上面的步骤应用到了你的示例代码中:
字符串
另一个需要知道的有用信息是,
exec
将更新lastIndex
,使其指向字符串中 * 在 * 返回的匹配之后的位置。这允许您执行许多操作,包括:1.重新运行相同的Regexp,它将自动查找最后一个匹配之后的下一个匹配。
1.如果下一个要解析的内容具有不同的模式,则将
lastIndex
值转移到不同的Regexp。1.将
lastIndex
值复制到非正则表达式解析所使用的变量中。1.将
lastIndex
返回给函数的调用方,这样调用方就可以按照自己的意愿处理字符串的其余部分。为什么
string.slice
和substring
也是很好的解决方案但是
myString.substring(idx)
似乎是一个相当昂贵的操作。不一定!尽管它们可能不会像Rust那样快,但所有领先的JavaScript引擎(SpiderMonkey,V8,JavaScriptCore)都完全符合您对Rust的描述。他们在幕后优化
string.slice
和substring
,使用指向源字符串的指针,而不是复制。Adventures in the land of substrings and RegExps有很多很棒的细节,图片和分析,但它已经五年了,事情可能会变得更好。下面是这个StackOverflow问题的答案:Is Javascript substring virtual?的