2016-05-09 9 views
0

私は、文字列、次のしているとしましょう属性:正規表現は

私は汎用の正規表現を、(タグ名は、変更する名前は属性変更){}内のコンテンツと一致するように書くことができますどのよう"<aa v={<dd>sop</dd>} z={ <bb y={ <cc x={st}>ABC</cc> }></bb> }></aa>"

いずれか<dd>sop</dd><bb y={ <cc x={st}>ABC</cc> }></bb>

正規表現は、私は"(\s*\w*=\s*\{)\s*(<.*>)\s*(\})"が正しくない

"<dd>sop</dd>} z={ <bb y={ <cc x={st}>ABC</cc> }></bb>"と一致して書きました。

答えて

2

一般的な正規表現では、良い方法で入れ子を扱う方法がありません。したがって、このような質問が起きると、すべてのワインティングが行われます。正規表現を使用してXML/HTMLを解析することはありません。

いくつかの単純なケースでは、それが有利かもしれません。あなたの例のように、ネスティングのレベルの数が限られている場合は、各レベルに対して1つの正規表現を追加するだけです。

ここで手順を実行してみましょう。あなたはこれが何が、閉じ括弧のいずれかの数字が続く開始ブレースと一致する

{[^}]*} 

使用することができます最初の非ネストされた属性を処理するには、最後に閉じ括弧が続きます。わかりやすくするために、私はそのような心臓部を非捕捉グループに入れます。

{(?:[^}])*} 

これは、代替のものを挿入するときに必要となるためです。

あなたは今

{(?:{[^}]*}|[^}])*} 
    ^^^^^^^ original regex inserted as alternative (to it self) 

のように、それは1を可能にし、また、ブレースの別のネストされたレベルになると、単純に最初の正規表現で参加する閉じ括弧[^}])が、その何のために許可されている場合ネスティングのレベル。再度同じことを、は入れ子の別のレベルを可能にする

{(?:{(?:{[^}]*}|[^}])*}|{[^}]*}|[^}])*} 
     ^^^^^^^^^^^^^^^ previous level repeated 

ように、それ自体に代わるものとして、この正規表現を結びます。これは、必要に応じてさらに多くのレベルで繰り返すことができます。

これは、あなたの質問があなたがそこでしたいことについてはっきりしていないので、属性名と物事のキャプチャを処理しませんが、それはあなたに1つの方法を示す(i.m.o.:P)正規表現の入れ子を扱う。

You can see it handle your example here at regex101

よろしくお願いいたします。

+0

ありがとうございました。私は '{'または '}'が '\ {' '\}'としてエスケープされるべきであることに気づいたでしょう。 – ma2s

+0

これは実際に私が知っているものからは必要ではありません。量子の形を取っていなければ、それは文字通り一致します。しかし、読みやすさのために - あなたの権利。 – ClasG

+0

がチェックされ、Javaは上記の例外であるように見えます;) – ClasG

0

バランスの取れた中カッコを処理しようとしています。これには再帰的な正規表現が必要です。定義上、再帰正規表現は規則的ではありません。とにかく、いくつかの言語がそれらをサポートしています。 Perl、PHP、ルビー。 Thisはこのトピックに関する良いチュートリアルです。

通常、yaccのような本格的なパーサーでこの種の情報を抽出する必要があります。

これはバランスの取られていないの中括弧:([ =]*)=(\{[^}]*\})を処理できる正規表現です。これは{<dd>sop</dd>}{st}と一致しますが、これは正しいです。残念ながら、{ <bb y={ <cc x={st}と一致しますが、これはあなたが望むものではありません。