4

我找不到让 JavaScript 正则表达式在字符串中间开始匹配的方法,用 '^' 绑定它(将正则表达式的开头锚定到我指定的起点)。

Perl 和 Python 有我需要的东西(尽管它们是完全不同的方法)。

在 Perl 我可以这样做:

$s = 'foo bar baz';
$r = qr/\Gbar/;
pos($s) = 4;
print 'OK' if $s =~ $r;

在 Python 中,我可以这样做:

s = 'foo bar baz'
r = r'bar'             # r'^bar' also works
if re.match(r, s[4:]): # re.match implies '^'
    print 'OK'

在 JavaScript 中(至少在 Node.js 中)我尝试:

s = 'foo bar baz';
r = /^bar/g;
r.lastIndex = 4;
if (r.exec(s))
    console.log('OK');

这是行不通的。如果我将第二行更改为:

r = /bar/g;

然后它确实匹配,但它也可以在 4 之后的任何位置匹配(我不想要)。

背景:我正在开发一个名为 Pegex 的多语言解析框架的 JavaScript 端口,其中每个终端都是一个正则表达式,在当前解析的位置(并锚定在它的前面)进行尝试。效率是一个问题。例如,在我的起点使用输入的子字符串副本将是最糟糕的解决方案。

我能想到的一种解决方案是将匹配项的“索引”值与我设置的 lastIndex 值进行比较,以查看它是否在开始时匹配。这会降低 '^' 的效率,但可能不会花费太多,因为 Pegex 正则表达式通常很小且没有回溯。

谁能想到更好的解决方案?

4

2 回答 2

3

匹配 "^.{4}actualre" 怎么样?

于 2012-08-05T19:00:25.917 回答
1

将字符数跳过到要开始匹配的位置是解决此问题的一个非常好的通用解决方案(恕我直言)。

s = 'foo bar baz';                                                          
r = 'bar';                                                                  
p = 4;                                                                      
r = new RegExp('^[\\s\\S]{' + p + '}' + r);                 
if (r.exec(s))                                                              
    console.log('OK');                                                      

我将不得不测试它在大数据上的表现,但我想它可能会非常好,具体取决于正则表达式的实现。例如,如果实现知道 [\s\S] 是在 JS 中请求任何字符(包括换行符)的常用方式,那么它可以简单地一次性向前索引。

还有什么好主意吗?:)

于 2012-08-05T19:19:33.680 回答