2009-06-26 5 views
0

私はJavaアプリケーションで使っている次の正規表現を持っています。場合によっては正しく動作しないこともあります。この正規表現をより一般的にするにはどうしたらうまくいくのですか?時にはうまく動作しないことがあります

<!-- <editable name=(\".*\")?> -->(.*)<!-- </editable> --> 

場合によっては前後に空白があります。テキストがあることもあります。タグ内の領域についても同様です。

主な問題は、name =(\ "。* \")?>は、想定されている以上に一致することがあります。私はそれが解決することが明らかであるかどうか、このコードを見るだけではわかりません。

+3

私には正規表現でXMLを処理しようとしているようです。どうしてそんなことをするのか? – Tomalak

+0

まあ、以前はXMLの解析を試みてきましたが、残りのページはdefintely valid XMLではないので動作しないようです。クリーンアップツールは、これをきれいにするのは難しいと感じているようです。私は自分自身で各ページに入っているこれらのタグを制御できるので、Regexが最良の方法だと思った。 – Ankur

答えて

0

*乗算器はデフォルトで「欲張り」です。つまり、パターンは可能な限り一致しますが、パターンは正常に一致します。

あなたは*を使用することによって、これを無効にする?そう試すことができます。

(\".*?\") 
1

名はある種の識別子である場合、私は、例えば[\w-]*とその.*を置き換えます。

または[^\"]*ですので、最後の二重引用符は取り込まれません。

編集:

他のポストで述べたように、あなたは代わりにプレーンな正規表現の簡単なDOMのトラバーサル、XPathのまたはXQueryによる評価プロセスのために行くことを検討してください。しかし、フィルタリング処理で正規表現を使用する必要があることに注意してください。正規表現に対してボディをテストするだけでターゲットのコメントを見つけることができるからです(サンプルが一定であることは疑いがあります)。

編集2:

それは、主要な末尾やコメント本体の内部空白ことかもしれないあなたのregexpは失敗します。 \s*を最初と最後に入れ、属性のようなものの前に\s+と置くことを検討してください。

<!--\s*<editable\s+name=(\"[^\"]*\")?>\s*-->(.*)<!--\s*</editable>\s*--> 

それとも、XMLベースの検索にフィルタリングされています

"\\s*<editable\\s+name=(\"[^\"]*\")?>\\s*" 
"\\s*</editable>\\s*" 

編集3:は二回エスケープを修正しました。ありがとうアランM

+1

\ wは文字、数字、アンダースコアと一致しますので、[\ w \ d \ - \ _]は[\ w-]である必要があります(ハイフンはリストされた最初の文字または最後の文字であればエスケープする必要はありません)。 –

5

XMLは通常の言語ではなく、HTMLや「ネスティング」構造を持つ他の言語でもありません。正規表現で解析しないでください。

Choose an XML parser。他の人が指摘したように

+3

入力データが入れ子になっていないことが保証されている場合でも、* MLは依然として非常に複雑なため、ハンドローリングされた正規表現は非常に狭いアプリケーションの外では正しくありません。したがって、現在のデータが正規表現で扱えるほどシンプルであっても、実際のXMLパーサーを使用してください。 –

+0

+1 - @Svante: "XML/HTML with regex"の投稿だけで日常の "200 rep" -capにすることは可能でしょうか? ;-) – Tomalak

+1

@ kd304、適切なパーサーを使用すると、一般に、間違ったツールを使用するよりも迅速かつ簡単になります。正規表現は魔法のブラックボックスではなく、通常の言語を解析するためのツールです。 – Svante

1

、「名前」に一致する貪欲.*(ドット-starが)属性は、(.*?)非貪欲またはより良い、否定文字クラス([^"]*)に置き換えるので、それを行う必要があります正規表現の残りの部分で何が起こっても、閉じ引用符を超えて一致することはできません。いったんそれを修正したら、他のドット・スターと同じ問題があるかもしれません。あなたはそれも非貪欲にする必要があります。

Pattern p = Pattern.compile(
    "<!--\\s*<editable\\s+name=\"([^\"]*)\">\\s*-->" + 
    "(.*?)" + 
    "<!--\\s*</editable>\\s*-->", 
    Pattern.DOTALL); 

空白に関するご意見の重要性はありません。改行やキャリッジリターンの場合、DOTALL修飾子はドットにマッチさせます。もちろん、\sもマッチします。

バックスラッシュが必要な場所と必要な場所の混乱を避けるために、これをJava文字列リテラルの形で記述しました。 "生の"正規表現では、各空白の短縮形(\s*)にバックスラッシュが1つしかなく、引用符をエスケープする必要はありません("[^"]*")。

+0

ああ、私の答えが病気になっていないことに気付かなかった。ありがとう。 – akarnokd

関連する問題