2011-01-21 3 views
5

私は一致したいLaTeX文書を持っています。そして、次のものにマッチするRegExマッチが必要です:PHPで正規表現を使用してネストされた中カッコをどのように一致させるのですか?

\ # the backslash in the beginning 
[a-zA-Z]+ #a word 
(\{.+\})* # any amount of {something} 

しかし、彼女はキャッチです。

最後の行では、1.それは貪欲である必要があり、2.一致する番号が{}である必要があります。

意味私は文字列を持っている場合\test{something\somthing{9}} それは全体に一致します。その順番にする必要があります({})。それは次のように一致しないように:\ TeXの{}のためのLaTeX {} \

される文書作成システムを

のLaTeX {} \だけ

\ TeX {}

ヘルプ誰ですか?たぶん誰かがマッチングの良いアイデアを持っているのでしょうか?正規表現を使用しないでください。

+2

ので、正規表現ではありません最善の選択。それは言われている、あなたは*できます*ほとんどの正規表現エンジンは、最近は定期的ではありませんが、それはまだ良い考えではありません。 –

+0

もし私が他の選択肢があれば、私はそれに向かいました。しかし私は、私が使うことができる他のことは知らない。ベターのアイデアはありますか?そうでなければ、私はRegExの幅に詰まっているようです。 – Knarf

+0

これは '{'と '}'(これは正規表現でできます)だけでなく '{}'が拒否されていることを確認したいのです( '{'と'}'!)、 '{'と '}'がコメント行に現れたときにそれらを破棄したいと思うでしょう。つまり、正規表現はこれには適していません。 –

答えて

2

これは再帰を行うことができます。

$input = "\LaTeX{} is a document preparation system for the \TeX{} 
\latex{something\somthing{9}}"; 

preg_match_all('~(?<token> 
     \\\\ # the slash in the beginning 
     [a-zA-Z]+ #a word 
     (\{[^{}]*((?P>token)[^{}]*)?\}) # {something} 
)~x', $input, $matches); 

これは正しく、\LaTeX{}にマッチし\TeX{}、それは再帰的な正規表現のマッチングをサポートしていますので、\latex{something\somthing{9}}

-1

残念ながら、私はこれは不可能だと思います。正規表現パーサのような有限状態マシンでは解決できない問題の例として、ブラケットマッチング(適切に対になったネストされた括弧を検出する)が一般的に使用されます。あなたは文脈自由文法でそれを行うことができますが、それは正規表現の仕組みではありません。あなたの最善の解決策は、最初のチェックのために{*[^{}]*}*のような正規表現を使用し、それが偶数であるかどうかをチェックする別の短いスクリプトです。

結論として、正規表現だけで試してみないでください。これは正規表現だけで解決できる問題ではありません。

2

PHP 使用することができます。 しかし、は、LaTeXのような文字列に{または}を持つコメントがあると失敗します。

デモ:

$text = 'This is a \LaTeX{ foo { bar { ... } baz test {} done } } document 
preparation system for the \TeX{a{b{c}d}e{f}g{h}i}-y people out there'; 
preg_match_all('/\\\\[A-Za-z]+(\{(?:[^{}]|(?1))*})/', $text, $matches, PREG_SET_ORDER); 
print_r($matches); 

生成:

Array 
(
    [0] => Array 
     (
      [0] => \LaTeX{ foo { bar { ... } baz test {} done } } 
      [1] => { foo { bar { ... } baz test {} done } } 
     ) 

    [1] => Array 
     (
      [0] => \TeX{a{b{c}d}e{f}g{h}i} 
      [1] => {a{b{c}d}e{f}g{h}i} 
     ) 

) 

簡単に説明

:それはあなたが一致させたい、正規のものではありません

\\\\   # the literal '\' 
[A-Za-z]+ # one or more letters 
(   # start capture group 1 <-----------------+ 
    \{   # the literal '{'       | 
    (?:  # start non-capture group A    | 
    [^{}] #  any character other than '{' and '}' | 
    |  #  OR         | 
    (?1)  #  recursively match capture group 1 ---+ 
)   # end non-capture group A 
    *   # non-capture group A zero or more times 
    }   # the literal '}' 
)   # end capture group 1 
関連する問題