2

一致が引用符内にない場合にのみ一致する pcre 正規表現を作成できますか? 正の先読みを使用して一致後に偶数があることを主張する正規表現を見てきましたが'、これは私の場合はほとんど機能しますが、奇数の引用符が and 内に表示される場合が{あり}ます。

文字列の例:a 'asdfasdfasdf' {' ' ' as'df'sdf}foo.bar 'asdf' { a' } asdf asdf foo.bar 'asdf' {a'} asdf'asdffoo.barasdf' 'foo.bar' asdf {'''}

引用符で囲まれていない場合に foo.bar を一致させる方法はありますか?

私の実際のユースケースでは、これを行うためのパーサーを既に構築していますが、最初に正規表現で解決しようとしましたが、欠けているトリックがあるかどうか疑問に思っていました。

4

1 に答える 1

2

引用符の外側で発生するパターンをチェックするだけの場合、解決策は簡単で、先読みでゲームをプレイする必要はありません。(複雑な先読みは、病的に遅い正規表現を生成するための常に良い方法です。) 一致の前に偶数の引用符があることを知ることは、その後に偶数の引用符があることを知ることと同じくらい有効であり、前者は潜在的な一致ごとに文字列全体を投機的に一致させる必要がないため、チェックがはるかに簡単かつ高速になります。ただし、貪欲でない繰り返しが必要です。そうしないと、最初の一致ではなく、最後の可能な一致が見つかります。

簡単な例を次に示します。

^(?:[^']*'[^']*')*?[^']*?foo\.bar
    |-paired 's|         |----------The pattern.
 |-shortest match-|
                   |----|
                   no quotes

{}しかし、あなたは実際には何らかの方法で特別にしたいとも思っています。あなたはそれについてはっきりしていないように見えるので、私はただ推測しています。ブラケットがネストできる場合、正規表現は適切ではありません。(「正規表現はカウントできません。」)

更新された要件(コメント内)に基づいて、

  1. 引用符で中括弧を隠す
  2. 中括弧は引用符を隠します
  3. 中かっこと引用符はどちらもターゲットを隠します。と
  4. ブレースはネストしません

解決策は、私が上で提案したものと大差ありません。{[^}]*}を初期パターンに追加するだけです。1 つの可能性を次に示します。

^(?:[^'{]*(?:'[^']*'|{[^}]*}))*?[^'{]*?foo\.bar

これは(あまり良くない)テストです。-o オプションを指定すると、grep は一致した部分を表示するため、各一致が終了する場所を確認できます。

$ grep -oP "^(?:[^'{]*(?:'[^']*'|{[^}]*}))*?[^'{]*?foo\.bar" <<\EOF
The target string is foo.bar and we should match the first foo.bar
'foo.bar' does not match but foo.bar does
Also, {foo.bar} doesn{'}t match, 'foo.bar' doesn{'}t match, {'foo.bar} doesn{'}t match, but foo.bar does
Note that {braces don't {nest so the end is here} and foo.bar matches}   
EOF

これは以下を生成します:

The target string is foo.bar
'foo.bar' does not match but foo.bar
Also, {foo.bar} doesn{'}t match, 'foo.bar' doesn{'}t match, {'foo.bar} doesn{'}t match, but foo.bar
Note that {braces don't {nest so the end is here} and foo.bar
于 2012-10-11T04:44:47.193 に答える