2009-07-13 10 views
45

<content>であるXMLタグ内のすべての改行文字(\n)と一致する正規表現を探しています。例えばその<content>タグ、内側:<content>タグ内のすべての改行文字( n)に一致する正規表現

<blog> 
<text> 
(Do NOT match new lines here) 
</text> 
<content> 
(DO match new lines here) 
<p> 
(Do match new lines here) 
</p> 
</content> 
(Do NOT match new lines here) 
<content> 
(DO match new lines here) 
</content> 
+2

正規表現にする必要はありますか? –

+0

Quartzの答えに従って、改行またはすべてのテキストのみをマッチさせますか? –

+0

はい、それは正規表現でなければならず、新しい行にのみ一致する必要があります。 –

答えて

66

は実際に...あなたは、少なくともではない1ここで、単純な正規表現を使用することはできません。あなたはおそらくコメントについて心配する必要があります!誰かが書くことがあります。

<!-- <content> blah </content> --> 

現在地二つのアプローチをとることができます。

  1. ストリップすべてのコメントを最初に。その後、正規表現のアプローチを使用します。
  2. 正規表現を使用せず、コメントにネストされているかどうかを追跡できるコンテキスト依存の解析手法を使用しないでください。

注意してください。

また、すべての新しい行を一度に一致させることはできません。 @Quartzはこの1つを提案した:

<content>([^\n]*\n+)+</content> 

これは、終了タグの前に改行文字を右に持っているすべてのコンテンツのタグが一致します...しかし、私はあなたがすべて改行を照合することによって何を意味するかわかりません。一致するすべての改行文字にアクセスできるようにしたいですか?その場合は、すべてのコンテンツタグを取得し、その間に入れ子になっている改行文字をすべて検索してください。もっとこのような何か:

<content>.*</content> 

しかし、一つCAVEATがある:正規表現は貪欲なので、この正規表現は最後の終値1に最初の開始タグと一致します。代わりに、あなたは正規表現を抑制しなければならないので、貪欲ではありません。 Pythonのような言語では、 "?"正規表現のシンボル。

私はこれを念頭に置いて、落とし穴のいくつかを見て、どのように進めたいかを考えていきたいと思います。おそらく、XML解析ライブラリを使用して、すべてのコンテンツタグを反復処理するほうがよいでしょう。

私は最善の解決策を提供することはできません知っているが、少なくとも私はあなたがこの中に困難を見ますと、なぜ他の答えは...

UPDATE 1右ではないかもしれない願っています:

もう少し要約して、私の返答にもっと詳細を加えてみましょう。 Pythonの正規表現の構文を使用するつもりです。(私に前もって許してください...いくつかの文字をエスケープする必要があるかもしれません...私の投稿にコメントして修正します):

コメントを削除するには、次の正規表現を使用します。 "?" 。*を非貪欲にすることを抑制する。

同様に、コンテンツタグを検索するには、 。*?試合は)(グループオブジェクトと

また、あなたはこれを試してみると、それぞれの改行文字にアクセスすることができる場合があります

<content>(.*?(\n))+.*?</content> 

私は私のエスケープがオフになっている知っているが、それはアイデアをキャプチャします。この最後の例はおそらくうまくいかないでしょうが、あなたが望むものを表現することがあなたの最善の策だと思います。私の提案は残っています:すべてのコンテンツタグをつかんで自分でやるか、パースライブラリを使用してください。

UPDATE 2:だからここ

は、Pythonのコードであることは、働くべきです。私はあなたが何を意味するのかまだ確信していますすべての改行を "見つける"。あなたは全体の行をしたいですか?または、改行の数を数えてください。実際の行を取得するには、試してみてください。

#!/usr/bin/python 

import re 

def FindContentNewlines(xml_text): 
    # May want to compile these regexes elsewhere, but I do it here for brevity 
    comments = re.compile(r"<!--.*?-->", re.DOTALL) 
    content = re.compile(r"<content>(.*?)</content>", re.DOTALL) 
    newlines = re.compile(r"^(.*?)$", re.MULTILINE|re.DOTALL) 

    # strip comments: this actually may not be reliable for "nested comments" 
    # How does xml handle <!-- <!-- --> -->. I am not sure. But that COULD 
    # be trouble. 
    xml_text = re.sub(comments, "", xml_text) 

    result = [] 
    all_contents = re.findall(content, xml_text) 
    for c in all_contents: 
     result.extend(re.findall(newlines, c)) 

    return result 

if __name__ == "__main__": 
    example = """ 

<!-- This stuff 
ought to be omitted 
<content> 
    omitted 
</content> 
--> 

This stuff is good 
<content> 
<p> 
    haha! 
</p> 
</content> 

This is not found 
""" 
    print FindContentNewlines(example) 

このプログラムは、結果を出力します。

['', '<p>', ' haha!', '</p>', ''] 

最初と最後の空の文字列はすぐに最初<p>を先行改行文字から来て、1は右後に来て</p>。すべてにおいて、このすべて(ほとんどの場合)がこのトリックを行います。このコードを試し、必要に応じて調整してください。真ん中に物を印刷すると、正規表現がマッチしているものとマッチングしていないものを見ることができます。

希望:-)。

PS - 新しい改行をすべてキャプチャするために私の最初のアップデートから正規表現を試してみるのは大したことはありませんでした。

+0

ここに正規表現のドキュメントがあります。上記のコードを書きました(Pythonの正規表現に慣れていないと便利です):http:///docs.python.org/library/re.html – Tom

+2

@Moayad:btw、ネストされたタグがある場合、このメソッドは確実に動作しません。正規表現はそれを処理できません。 Regexesは実際にこの問題には適していません。 – Tom

+0

この詳細な説明に感謝します:) それは私がその問題をどうするかを決めるのを助けるでしょう。 もう一度おねがいします! –

4
<content>(?:[^\n]*(\n+))+</content> 
+1

定量器を非貪欲にするのはどうですか? ([^ \ n] *?\ n +?)+?

+0

@Codebender、あなたのコードは< content>タグ内のすべてのものと一致しますので、新しい行だけを一致させたいと思います。 –

+0

Quarz、ありがとう、それは私が探しているものではありません、あなたの正規表現は、最初の開始タグ< content>と最後の終了タグ< /content>の間のすべての文字と一致します。私は少し明確にするために例を更新しました。 –

関連する問題