我正在使用 Javascript 解析一个中等复杂的语法,我想使用正则表达式来匹配标记,例如数字。
给定一个包含语法的字符串、一个表示数字(比方说)的正则表达式和字符串中的一个偏移量,我想找出正则表达式是否与该偏移量处的字符串完全匹配。
我可以设置 lastIndex,调用 RegExp.exec 并检查结果匹配的索引属性以查看匹配是否发生在预期的偏移处,但这是非常低效的,因为如果没有找到,exec 将搜索整个字符串在起始偏移处匹配。
Javascript 规范说“模式评估(”编译)为内部过程值。RegExp.prototype.exec 然后可以将此过程应用于字符串和字符串中的偏移量以确定模式是否匹配从正是字符串中的那个偏移量。”
这正是我想要的,但似乎没有办法访问这个内部函数。有没有人知道有没有?
附言我目前通过将输入字符串拆分为标记数组来避免这个问题,但我不想这样做。
最佳答案
我已经彻底测试了可能有效的方法,请参阅 JSPerf: ~20000 个字符, ~1000000 个字符。我创建了一个函数来生成由字母数字字符组成的随机字符串。运行此函数一次后,将创建一个 RegExp 模式,以在给定偏移量处匹配长度为 10 的字符串。
测试用例(当if(..)
中的条件为真时,在偏移index
处找到模式):
var string = "...about 20000 characters: A-Z a-z 0-9...";
var regexp = /abcdef1324/g;
var regexpSubstr = /^abcdefg1234/;
var index = 10000;
/*1*/ if ( regexpSubstr.exec(string.substr(index,10)) ) ;
/*2*/ regexp.lastIndex = index;
var found = regexp.exec(string);
if (found && found.length + index == regexp.lastIndex ) ;
/*3*/ if ( regexpSubstr.test(string.substr(index,10)) ) ;
/*4*/ // Only when the RegExp matches a fixed number of characters
regexp.lastIndex = index;
if ( regexp.test(string) && regexp.lastIndex == index + 10 ) ;
案例 1 和 案例 3 是等价的,因为它们检查子字符串是否匹配 /^abcdef1234/
模式(是否选定的子字符串以“abc..etc”开头?)。
案例2和案例4使用.lastIndex
方法:
1. 将 RegExp 的 .lastIndex
属性设置为所需的偏移量
2. 检查是否找到模式。
3. 检查找到的模式是否位于偏移 index
处。
这些方法需要一个正则表达式来启用全局标志。
对于非常大的字符串,方法 4 (lastIndex
+ test
) 是 proved to be most efficient whn 在偏移量处发生匹配。然而,方法 4 要求匹配的模式具有预定义的固定大小。
方法 3 (substr
+ test
) 在给定位置发生匹配时比方法 4 稍慢。但是,当在大字符串中找不到匹配项时,方法 3 是 significantly faster比方法4。方法1和方法3似乎是equally fast当找不到匹配项时。
正则表达式方法
.exec
似乎并不比 .test
更有效率。 match
方法不适合这种情况,因为它会尝试查找所有匹配项,而不考虑 .lastIndex
属性。另一个可能的 RegExp 函数是 .search
函数,与之前显示的方法相比,它对于大字符串来说要慢得多。
关于javascript - Javascript RegExp 是否可以在不搜索的情况下匹配精确的字符串偏移量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7853176/