「任意の文字」の最もパフォーマンスの高いマッチング


8

https://www.emacswiki.org/emacs/MultilineRegexp 1は、使用にヒントを見つけます

[\ 0- \ 377 [:nonascii:]] * \ n

標準の代わりに

。* \ n

巨大なテキスト(37 KB)のスタックオーバーフローを回避するために、改行までの任意の文字を照合します。ここでのオーバーフローは懸念事項ですか、それとも前者のマッチング実行は後者よりもパフォーマンスが高いですか?

回答:


9

Emacsの正規表現で.は、すべての文字とは一致しません。これはの同義語です[^\n]。したがって、使用する理由[\0-\377[:nonascii:]]は、「任意の文字、改行も」に一致させたい場合です。

スタックをオーバーフローするWRTは、.*\n非常に効率的に処理する必要があります。つまり、バックトラックせず、スタックを使い果たすことはありません。それどころか[\0-\377[:nonascii:]]*\n、Emacsの正規表現エンジンは、一致するすべての文字に対してスタックのビットを使い果たし、「巨大な」テキストではスタックからオーバーフローする傾向があるため、かなり非効率的に処理されます。

emacswikiが提案し、提案[\0-\377[:nonascii:]]*しないことに注意してください[\0-\377[:nonascii:]]*\n


説明をありがとう。ただし、スタックオーバーフローの場合、[\ 0- \ 377 [:nonascii:]] * \ nによってオーバーフローが発生してもよろしいですか?これは、wikiが主張するものとは逆です。これは最後の\ nのbcsですか?次に、終了文字のない[\ 0- \ 377 [:nonascii:]] *のようなパターンはどのような用途になりますか?
Vroomfondel

「何か」に一致する正規表現はスタックスペースを消費します(つまり、Emacsの正規表現エンジンを使用した場合)。なぜそう[\0-\377[:nonascii:]]*なるのかわかりません\\(.\\|\n\\)*。だから、これはemacswikiが間違っていると思います。
Stefan

この問題について正式に明確にする方法(または誰でも)はありますか?
Vroomfondel 2016年

@Vroomfondelでテストしてご覧ください。の正規表現で|はバックトラックがさらに必要になる可能性があると想像できますが、実際にそうであるかどうかは、コンパイル方法によって異なります。
npostavs 2016年

3
これは、正規表現がで終わる場合にのみ当てはまります[\0-\377[:nonascii:]]*(このpoint-maxような正規表現で検索するのではなく使用することもあるので、これはかなり珍しいことです)(好奇心が強い:問題の核心は、一致できる文字のセットが*が*内で一致する可能性のある文字のセットから切り離された後。それが切り離されている場合、正規表現エンジンは中間ステップの記録をスキップするため、スタックスペースの浪費を回避します。したがって、スタックを消費しない.*\n[^a]*aください。.*aします)。
Stefan
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.