正規表現と「後方参照」を使用した「括弧のキャプチャ」


7

正規表現(RE)は有限オートマトン(FA)で実装されています。REの一部の言語(JavaScriptなど)には、「後方参照」を使用した「括弧のキャプチャ」などの機能があります。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#special-capturing-parentheses

(x)次の例に示すように、「x」に一致し、一致を記憶します。括弧はキャプチャ括弧と呼ばれます。パターン/(foo)(bar)\ 1 \ 2 /の「(foo)」と「(bar)」は、文字列「foo bar foo bar」の最初の2つの単語と一致し、覚えています。パターンの\ 1と\ 2は、文字列の最後の2つの単語と一致します。

このパターン/(foo) (bar) \1 \2/が実際に、私たちが理論的な形式言語で持っているREの定義に従ったREであるのか、それともより強力なものであるのかを知りたいのです。そうであれば、この種の機能がFAでも実装されているのか、それとも別の方法で実装されているのか(特に、実装方法)を知りたいと思います。



この違いによる実際の(実装レベル)パフォーマンスへの影響についての優れた説明については、swtch.com /〜rsc / regexp / regexp1.htmlを参照してください。(編集:この回答から既にリンクされているようです。)
ワイルドカード

回答:


7

オートマトン理論のREはFAと同等ですが、プログラミング言語(regexp)の場合、これは当てはまりません。

プログラミング言語の正規表現(PCREなど)は、オートマトン理論の正規表現(タイプ3)よりもはるかに強力です。

一致する括弧は通常でも文脈自由でもありません。文脈依存の機能です。ただし、問題のRegExpはタイプ2またはタイプ1を完全にはサポートしていません。

ブラケットマッチングはFAを介して実装されません。PCREの場合、推測とバックトラックによって実装されます。

PCREに関するPerl Monksの説明をご覧ください


ありがとうございました。次に、この場合、RegExpは(正式な)言語の乱用です。
asv 2017年

5
さて、それは名前の衝突です。当初のアイデアはREのようなものでしたが、それが進化したときでも名前は残っていました。
邪悪な

1
@asv:キャプチャが導入されてからしばらくの間、キャプチャグループを含むREは拡張正規表現またはEREと呼ばれていました。その後、PerlがREのバージョンを導入してからしばらくの間、正規表現と呼ばれ、POSIXの標準化された正規表現およびEREと区別されました(正規表現と正規表現に注意)。最近の人々は気にしません。
slebetman 2017年

9

これらの正規表現の拡張された概念は、通常の言語だけではありません。たとえば([ab]*)\1、言語に一致します{www{a,b}}、これは規則的ではなく、コンテキストフリーでもありません(Sipserの例2.38 、計算理論入門、第3版)。

正規オートマトンは正規言語にのみ一致するため、正規言語に一致しない「正規」式は有限オートマトンに変換できません。これの副作用は、多くのライブラリーがコンパイルしてオートマトンにしようとさえしないことです。これにより、「正規」式が真の正規表現であっても、マッチングが非常に遅くなる可能性があります。ラス・コックスはこれについても優れた記事を書いており、これは多くの歴史にも当てはまります。


あなたの例とこれらの情報をありがとう。:)
asv 2017年

8

答えはおそらく、あなたが尋ねようとしていることに対する答えですが、あなたが尋ねていることに対する答えではありません。

このパターン/(foo) (bar) \1 \2/が実際に、私たちが理論的な形式言語で持っているREの定義に従ったREであるのか、それともより強力なものであるのかを知りたいのです。そうであれば、この種の機能がFAでも実装されているのか、それとも別の方法で実装されているのか(特に、実装方法)を知りたいと思います。

実際、これ有限オートマトンで実装できる正規表現です。なぜなら、\1が評価されることが保証されfoo、に評価されること\2保証されているからbarです。

したがって、正規表現エンジンはこの事実を使用して、提案した言語を正確に記述する有限オートマトンを実際に作成できます。

ただし、キャプチャを条件付きにすると、他の人が述べたように、これは偽になる可能性があります。

(のような言語はまだ FAで記述できるため、問題が発生する可能性があることに注意してください。十分な条件ではなく、必要な条件のみを指定しました。編集:条件付きである必要はなく、十分ではありませんが、有限オートマトンに変換することもできますが、変換することはできません。/(a(aa|aa)|(aa|aa)a)\1\2/ /(a*)\1//(ab*)\1/


「かっこをキャプチャーする」という特定のパターンがREになることがあります。良い観察。
asv

@asv:うん。また、ここ(私のものを含む)のすべての回答について誤解を招く別のことは、問題は括弧自体のキャプチャではなく、それらを参照する後方参照にあるということです。かっこのキャプチャは、後方参照がない限り、バックトラックなしで処理できることを読んだことを覚えています。ただし、これが有限オートマトンを使用して実際に実行できるかどうかの背後にある詳細はわかりません(私の印象はそれが可能であると思いますが、正確にはわかりません)。しかし、LR解析やそのようなものを介してなど、バックトラックなしでそれらを処理する他の方法があるはずです。
user541686 2017年

はい、問題は次のとおりです。後方参照
asv '

0

特定の正規表現の実装は、DFAを構築しません。たとえば、java.util.regex OpenJDK実装はそうではありません。その結果、そのマッチング時間は、dk.brics.automatonのようなDFAコンパイル済み実装よりも遅くなります。しかし、後者は、基礎となる実装の結果として、キャプチャグループをサポートしていません。


NFA-> DFAの構築は非常に高価になる可能性があることに注意してください(2 ^#nodes)。
18

そうそう、指摘してくれてありがとう。DFAベースの実装の一致時間のみが短いことを反映するように、回答を更新しました。
vuamitom 2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.