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');

これは機能しません。2行目を次のように変更すると:

r = /bar/g;

その後、一致しますが、4 以降の任意の位置でも一致する可能性があります (これは望ましくありません)。

背景: 私は、Pegex と呼ばれる多言語解析フレームワークの JavaScript ポートに取り組んでいます。ここでは、すべての端末が、現在解析されている位置で試行される (そしてその前に固定されている) 正規表現です。効率性が懸念事項です。たとえば、私の出発点で入力の部分文字列のコピーを使用することは、最悪の解決策です。

私が考えることができる 1 つの解決策は、一致の 'index' 値を設定した lastIndex 値と比較して、最初に一致したかどうかを確認することです。これは '^' の効率を台無しにしますが、Pegex 正規表現は一般に小さく、ブラックトラッキングがないため、それほどコストはかからないかもしれません。

誰でもより良い解決策を考えることができますか?

4

2 に答える 2

1

照合を開始する文字数をスキップすることは、この問題に対する非常に優れた一般的な解決策です(imho)。

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 に答える