2016-06-20 4 views
0

私はURLからタプルを抽出しようとしていると私はre.search(pattern_str, text_str)を使用して文字列テキストタプルを抽出することができました。しかし、私はre.findall(pattern_str, text_str)を使ってタプルのリストを抽出しようとしたときに立ち往生しました。findallを使ってタプルを抽出するには?

テキストは次のようになります。

<li> 
    <a href="11111"> 
    some text 111 
    <span class="some-class"> 
     #11111 
    </span> 
    </a> 
</li><li> 
    <a href="22222"> 
    some text 222 
    <span class="some-class"> 
     #22222 
    </span> 
    </a> 
</li><li> 
    <a href="33333"> 
    some text 333 
    <span class="some-class"> 
     #33333 
    </span> 
    </a> 
... # repeating 
... 
... 

と私はタプルを抽出するために、次のパターン&コード使用しています:

text_above = "..." # this is the text above 
pat_str = '<a href="(\d+)">\n(.+)\n<span class' 
pat = re.compile(pat_str) 
# following line is supposed to return the numbers from the 2nd line 
# and the string from the 3rd line for each repeating sequence 
list_of_tuples = re.findall(pat, text_above) 

for t in list_of tuples: 
    # supposed to print "11111 -> blah blah 111" 
    print(t[0], '->', t[1]) 

は、たぶん私はその多分、不可能&奇妙な何かをしようとしているがプリミティブな文字列操作を使ってデータを抽出するほうがいいです...しかし、解決策がある場合は?

+5

:あなただけのリストタグ内のアンカーをしたい場合は

[(a["href"].strip(), a.find(text=True).strip()) for a in soup.find_all("a")] 

また、あなたは、特にそれらを解析することができます。美しいスープのようなパーサーを使用してください! –

答えて

1

を使用BeautifulSoupのようなHTMLパーサ:

from bs4 import BeautifulSoup 

h = """<li> 
    <a href="11111"> 
    some text 111 
    <span class="some-class"> 
     #11111 
    </span> 
    </a> 
</li><li> 
    <a href="22222"> 
    some text 222 
    <span class="some-class"> 
     #22222 
    </span> 
    </a> 
</li><li> 
    <a href="33333"> 
    some text 333 
    <span class="some-class"> 
     #33333 
    </span> 
    </a>""" 

soup = BeautifulSoup(h) 

あなたはスパンにHREFとprevious_siblingを取得することができます:

print([(a["href"].strip(), a.span.previous_sibling.strip()) for a in soup.find_all("a")]) 
[('11111', u'some text 111'), ('22222', u'some text 222'), ('33333', u'some text 333')] 

またはHREFと最初のコンテンツF ROMアンカー:だけではなく、子供からタグのテキストを取得する

print([(a["href"].strip(), a.contents[0].strip()) for a in soup.find_all("a")]) 

.find(text=True)と。正規表現でHTMLを解析しないでください

[(a["href"].strip(), a.contents[0].strip()) for a in soup.select("li a")] 
+0

私の意図は、 're.search()'と 're.findall()'に慣れて慣れることでした。私は 'bs4'を使って簡単に逃げることができますが、もう一度試してみましょう(* regex *を学んだ後で)。 – ssd

+0

それは私に私の髪を引っ張ったが、最終的に**正規表現**でそれをやった。しかし、公正であるために、私はそれを試してみましたw/** bs4 ** ... Voila!それは他にはないように時間を節約している。ありがとう。 – ssd

2

あなたの正規表現は、\n<spanの空白(字下げ)を考慮していません。 (そして、あなたがキャプチャしたい行の先頭に空白が、それもないが、問題の限りではありません。)それを修正するには、あなたには、いくつかの\s*追加できます示唆されているようにコメントして

pat_str = '<a href="(\d+)">\n\s*(.+)\n\s*<span class' 
+0

まあ...それは私のせいだ。合理的な解決策に見えました。だから、私は 'pat_str = ' [\ n \ s] *(。+)[\ n \ s] * ssd

+1

@ merkez3110デフォルトでは、regexは貪欲に動作します。あなたがやったやり方では、可能な限り大きなマッチを見つけようとします。そのマッチは最初の 'href'から最後の' span'にわたります。どちらかを、* *の代わりに '*?'で非貪欲なものにするか、私のバリアントを使うだけです。 –

+0

私はどこかに行っています...あなたが気にしない最後の質問です:コンパイルステートメントで 're.DOTALL'を使う方が良い解決法ですか、' \ n'文字に残すべきですか? ? – ssd

関連する問題