0

この質問は PCRE に関係しています。

この構文で使用されるネストされた括弧の再帰的検索を見てきました。

\(((?>[^()]+)|(?R))*\)

これに関する問題は、' [^()]+ ' は改行を含む任意の文字に一致できますが、中括弧、大括弧、句読点、単一文字などの単一文字のみに一致することを強制されることです。

私がやろうとしているのは、「(」と「)」の文字を任意の種類のパターン (「BEGIN」や「END」などのキーワード) に置き換えることです。

私は次の構成を思いつきました:

(?xs)  (?# <-- 'xs' ignore whitespace in the search term, and allows '.'
               to match newline )
(?P<pattern1>BEGIN)
(
   (?> (?# <-- "once only" search )
      (
         (?! (?P=pattern1) | (?P<pattern2>END)).
      )+
   )
   | (?R)
)*
END

これは実際には次のようなもので機能します。

BEGIN <<date>>
  <<something>
    BEGIN
      <<something>>
    END <<comment>>
    BEGIN <<time>>
      <<more somethings>>
      BEGIN(cause we can)END
      BEGINEND
    END
  <<something else>>
END

これは、ネストされた BEGIN..END ペアと一致します。

名前付きパターンpattern1pattern2BEGINENDにそれぞれ設定しました。検索語でpattern1を使用すると問題なく動作します。ただし、検索の最後にpattern2を使用することはできません。「 END 」と書き出す必要があります。

この正規表現を書き直して、パターンを一度だけ指定し、コード内の「どこでも」使用するだけでよいという考えはありますか? つまり、検索の途中でも最後でもENDを書かなくてもいいということです。

4

2 に答える 2

3

@Kobis の回答をさらに拡張するには、次の正規表現を参照してください。

(?xs)
(?(DEFINE)
        (?<pattern1>BEGIN)
        (?<pattern2>END)
)
(?=((?&pattern1)
(?:
   (?> (?# <-- "once only" search )
      (?:
         (?! (?&pattern1) | (?&pattern2)) .
      )+
   )*
   | (?3)
)*
(?&pattern2)
))

この正規表現を使用すると、個々のデータ ブロックごとにデータをフェッチすることもできます。最初の 2 つは定義ブロックで定義されているため、3 番目の後方参照を使用します。

デモ: http://regex101.com/r/bX8mB6

于 2014-05-28T17:54:27.403 に答える