2016-04-16 18 views
-3

私は次の文字列があるとします。のfindAll()の挙動(のpython 2.7)

"<p>Hello</p>NOT<p>World</p>" 

を、私は私が仕事

ための次のスクリプトを作成した単語 HelloWorld

を抽出したいです

#!/usr/bin/env python 

import re 

string = "<p>Hello</p>NOT<p>World</p>" 
match = re.findall(r"(<p>[\w\W]+</p>)", string) 

print match 

私は特に< p>と</p>を取り除くことに興味はありませんので、スクリプト内でそれをやっていることは決してありませんでした。

インタプリタプリント

ので、明らかに最初< Pを見>と最後</P>タグの間には無視しています。 findall()すべての3つの一致する文字列を返すべきではありませんか? (それが印刷する文字列と2つの単語)。

もしそうでなければ、どうすればコードを変更できますか?

PS:これはプロジェクト用で、私は私が必要としていることをするための代替方法を見つけました。これは私が推測する教育的理由によるものです。

+1

http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags – BrenBarn

答えて

1

[\w\W]+が、それは(あなたの<p></p>すべてのタグを含む)することができますようとして多くののものと一致しますので、あなたがシングルマッチで全体の内容を取得する理由があります。これを防ぐには、?を追加して貪欲でないバージョンを使用します。 documentationから

match = re.findall(r"(<p>[\w\W]+?</p>)", string) 
# ['<p>Hello</p>', '<p>World</p>'] 

*?+???
'*''+'、及び'?'修飾子はすべて貪欲です。彼らはできるだけ多くのテキストに一致します。場合によっては、この動作が望ましくない場合もあります。 RE <.*><a> b <c>と一致する場合は、<a>だけでなく、文字列全体と一致します。修飾子の後に?を追加すると、貪欲でないか、または最小限の方法で一致が実行されます。可能な限り少数の文字が一致します。 RE <.*?>を使用すると、<a>と一致します。

あなたは結果に<p></p>タグをしたくない場合は、先読みを使用して、結果に含めないようにアサーションの後ろに見えることになるでしょう。サイドノートとして

match = re.findall(r"((?<=<p>)\w+?(?=</p>))", string) 
# ['Hello', 'World'] 

あなたが正規表現でHTMLやXMLを解析しようとしている場合しかし、HTMLを解析することを意図されるようBeautifulSoupとしてライブラリを使用することが好ましいです。

+0

ありがとうございました。私はREの一部を見落としたと思います – persongr

+0

私はBeautifulSoupも見ていきます。提案に感謝します。 – persongr

+0

+1 BeautifulSoup(または類似)。 HTMLは通常の言語ではないので、正規表現はそれらを解析するのには適していません。 HTMLを理解しているライブラリを使う方がはるかに簡単です。 – nighthawk454