2015-05-01 41 views
-4

我試圖創建一個正則表達式來提取電話的StreetAddress從HTML網頁頁面值(9440717256,H.No。62年3月11日,RTC殖民地..)在python中。這三個領域都是可選我想這正則表達式,但輸出是不一致的可選字正則表達式

telephone\S+>(.+)</em>.*(?:streetAddress\S+(.+)</span>)?.*(?:pages\S+>(.+)</a></span>)? 

樣本串

<em phone="**telephone**">9440717256</em></div></div></li><li class="row"><i class="icon-sm icon-address"></i><div class="profile-details"><strong>Address</strong><div class="profi`enter code here`le-child"><address itemprop="address" itemscope="" itemtype="http://schema.org/PostalAddress" class="data-item"><span itemprop="**streetAddress**">H.No. 3-11-62, RTC Colony</span>, <span>Vastu Colony, </span><span class="text-black" itemprop="addressLocality"><a href="/hyderabad/lal-bahadur-nagar/allcategory.aspx" title="**Pages**">Lal Bahadur Nagar</a></span> 

誰能幫助我建立正則表達式嗎?

+2

請不要這樣做! [可怕的事情](http://blog.codinghorror.com/parsing-html-the-cthulhu-way/)將會發生。 –

+1

你想要一個HTML解析器,然後潛入正確的領域。 – AlG

+0

@Tichodrama我已經閱讀了整篇文章,並且實際上只要您小心,就可以使用正則表達式來進行html解析。 – Shashank

回答

1

如果您知道HTML提供程序,裏面的代碼是什麼樣子,正則表達式可以安全使用。

然後,只需使用替代和命名捕獲組。

telephone[^>]*>(?P<Telephone>[^<]+)|streetAddress[^>]*>(?P<Address>[^<]+)|Pages[^>]*>(?P<Pages>[^<]+) 

demo

如果>是不會被序列化,你可以使用這個表達式(更普遍的一個,編輯:現在,詳細):

telephone[^<]*>  # Looking for telephone 
    (?P<Telephone>[^<]+) # Capture telephone (all text up to the next tag) 
| 
streetAddress[^<]*> # Looking for streetAddress 
    (?P<Address>[^<]+) # Capture address (all text up to the next tag) 
| 
Pages[^<]*>   # Looking for Pages 
    (?P<Pages>[^<]+)  # Capture Pages (all text up to the next tag) 

Sample demo on IDEONE

粘貼正則表達式代碼部分:

p = re.compile(ur'''telephone[^<]*>  # Looking for telephone 
    (?P<Telephone>[^<]+) # Capture telephone (all text up to the next tag) 
| 
streetAddress[^<]*> # Looking for streetAddress 
    (?P<Address>[^<]+) # Capture address (all text up to the next tag) 
| 
Pages[^<]*>   # Looking for Pages 
    (?P<Pages>[^<]+)  # Capture Pages (all text up to the next tag)''', re.IGNORECASE | re.VERBOSE) 
test_str = "YOUR STRING" 
print filter(None, [x.group("Telephone") for x in re.finditer(p, test_str)]) 
print filter(None, [x.group("Address") for x in re.finditer(p, test_str)]) 
print filter(None, [x.group("Pages") for x in re.finditer(p, test_str)]) 

輸出(加倍的結果是我的複製與不同的節點順序輸入字符串的結果):

[u'9440717256', u'9440717256'] 
[u'H.No. 3-11-62, RTC Colony', u'H.No. 3-11-62, RTC Colony'] 
[u'Lal Bahadur Nagar', u'Lal Bahadur Nagar'] 
+0

我看不出像這樣的正則表達式與HTML解析器相比有什麼優勢。 –

+0

這是更短,更快閱讀。 –

+0

更短什麼? –

3

考慮到你的輸入是無效的HTML,它可能會有所變動,你可以使用一個HTML解析器,如BeautifulSoup如果您的輸入更改,這些簡單的選擇器將不得不進行調整。

from bs4 import BeautifulSoup 

h = """<em phone="**telephone**">9440717256</em></div></div></li><li class="row"><i class="icon-sm icon-address"></i><div class="profile-details"><strong>Address</strong><div class="profi`enter code here`le-child"><address itemprop="address" itemscope="" itemtype="http://schema.org/PostalAddress" class="data-item"><span itemprop="**streetAddress**">H.No. 3-11-62, RTC Colony</span>, <span>Vastu Colony, </span><span class="text-black" itemprop="addressLocality"><a href="/hyderabad/lal-bahadur-nagar/allcategory.aspx" title="**Pages**">Lal Bahadur Nagar</a></span>""" 
soup = BeautifulSoup(h) 

編輯:既然你現在告訴我們,你想要一個有特定屬性值,你可以use a function as filter元素的文本

def find_phone(tag): 
    return tag.has_attr("phone") and tag.get("phone") == "**telephone**" 

def find_streetAddress(tag): 
    return tag.has_attr("itemprop") and tag.get("itemprop") == "**streetAddress**" 

def find_pages(tag): 
    return tag.has_attr("title") and tag.get("title") == "**Pages**" 


print(soup.find(find_phone).string) 
print(soup.find(find_streetAddress).string) 
print(soup.find(find_pages).string) 

輸出:

9440717256 
H.No. 3-11-62, RTC Colony 
Lal Bahadur Nagar 
+1

儘管我之前說過,但這可能是解決手頭問題的最佳解決方案。 +1 – Shashank

+1

如果在討論協議結束時可以達成一致,總是很好:) –

+0

@Tichodroma - 謝謝,這看起來很簡單。你可以讓知道如何獲得價值(9440717256,H.No.3-11-62,RTC殖民地..),而不是**電話,**街道地址** –