2016-11-25 4 views
0

私はバックトラッキング正規表現エンジンを使用するPerlで作業しています。余分なバックトラックをせずに/ s * a s * b /のようなregexpsをどのように一致させることができますか?

空白で区切られたトークンの文字列を一致させる必要があります(誰かが疑問に思っている場合に備えて、私はアセンブラを解析しています)。私は現在、

s/(\.text\n\s*\.align .(?:,0x90)?\n)\.globl\s+.*_?__stg_split_marker.*\n/$1/m 

のような正規表現を使用していますが、余分なバックトラックが心配です。

どうすればこの問題を防ぐことができますか?

+0

あなたは(テストをすることが有用である)あなたの例の文字列を表示する必要があります。私の意見では、主な問題は非常に容認しやすい '。* 'から来ています。その他のもの:m修飾子を使用する理由前にアセンブラパーサモジュールを探しましたか? –

+0

'。* _?'は '。* 'に簡略化することができます – ikegami

答えて

1

一般的なアプローチは、禁止するバックトラックを行う可能性のあるすべてのサブ式に対して、サブ式を(?>...)で囲みます。例えば、 \s+は、(?>\s+)となります。

+0

キャプチャを禁止するには'(?:...) 'と組み合わせることができますか? – Demi

+1

@Demi: '(?> ...)'(原子グループ) '(?:...)'(非キャプチャグループ)はキャプチャしません。しかし、これらのグループの1つがマッチ結果全体から何かを削除するとは思わないでください。アトミックに量指定子を持つ単一のトークンを作成したい場合は、量指定子の後に '+'をつけて所有権を持たせることもできます: '\ s ++'(この機能が正規表現のフレーバーで利用可能な場合) –

0

私の経験では、多くの人がnot requiredの正規表現を使用しようとしており、多くの人がそれらを避けようとしていますwhere they're the best solution。だから私はいつも頼むことから始める必要があります - あなたは何をしようとしていますか?

私の見た目は、コードを分解しようとしていることです。おそらく、それを逆にするのは簡単でしょうし、常にそれを引き離してから、それをmakeプロセスの一部として結合するのは簡単でしょうか?このタイプのものでは、テンプレートを使用してコードを正確に作成し、このビルドユニットの特定のコードに補間することがよくあります。そして、私は正規表現の問題を完全に避けます。つまり、私は6ヶ月後には期待していないことを開発者が避けることができます。

+0

コードは、GHC NCG(ネイティブコードジェネレータ)、LLVM、またはGCCから出力されます。だから私はソースを制御することはできません(いいです、私が取り組んでいるツールはGHCの一部なので、GHC NCGならそうしますが、それ以外の方法はありません)。 – Demi

0

正直、このコードではほとんどバックトラックしていないはずです。すべてが.textによって固定され、バックトラッキングが発生する可能性がある他の場所はすぐに中止されます。それでも、あなたが試すことができる最適化があります。

  • \Kを使用してキャプチャする必要性を取り除きました(遅くなる)。私が上記のことを考えれば、これは最も有益な最適化であろう。
  • \s*\s*+ aka (?>\s*)に置き換えます(バックトラックを防止します。これは、次の文字をスペースにすることができないため安全です)。
  • .*.*+ aka (?>.*)に置き換えます(バックトラックを防止します。これは、次の文字が改行ではないため安全です)。
  • (?:,0x90)?をと置き換えます(バックトラックを防止します。これは、次の文字をカンマにすることができないため安全です)。
  • \s+.*_?を、より簡単で同等の\s.*に置き換えてください。

s/ 
    \.text \n 
    \s*+ 
    \.align [ ] .(?:,0x90)?+ \n 
    \K 
    \.globl \s .* __stg_split_marker .*+ \n 
//xm 
関連する問題