2013-05-26 67 views
2

我想從Enom API調用中建立一個域名列表。我找回了很多信息,需要找到域名相關的行,然後將它們結合在一起。在Python中的正則表達式

是來自eNom的背面的串看起來有點像這樣:

SLD1=domain1 
TLD1=com 
SLD2=domain2 
TLD2=org 
TLDOverride=1 
SLD3=domain3 
TLD4=co.uk 
SLD5=domain4 
TLD5=net 
TLDOverride=1 

我想從建立一個列表,它看起來像這樣:

[domain1.com, domain2.org, domain3.co.uk, domain4.net] 

要找到不同的域名稱組件我嘗試過以下(其中「enom」是上面的字符串),但只能得到SLD和TLD匹配。

re.findall("^.*(SLD|TLD).*$", enom, re.M) 

回答

3

這對你的作品例如,

>>> sld_list = re.findall("^.*SLD[0-9]*?=(.*?)$", enom, re.M) 
>>> tld_list = re.findall("^.*TLD[0-9]*?=(.*?)$", enom, re.M) 
>>> map(lambda x: x[0] + '.' + x[1], zip(sld_list, tld_list)) 
['domain1.com', 'domain2.org', 'domain3.co.uk', 'domain4.net'] 
6

編輯: 每當我看到一個問題,問的正則表達式的解決方案我有這個奇怪的衝動,試圖解決它沒有正則表達式。大多數情況下,它比使用正則表達式更有效,我鼓勵OP測試哪個解決方案最有效。

這裏是原始的方法:

a = """SLD1=domain1 
TLD1=com 
SLD2=domain2 
TLD2=org 
TLDOverride=1 
SLD3=domain3 
TLD4=co.uk 
SLD5=domain4 
TLD5=net 
TLDOverride=1""" 

b = a.split("\n") 
c = [x.split("=")[1] for x in b if x != 'TLDOverride=1'] 
for x in range(0,len(c),2): 
    print ".".join(c[x:x+2]) 

>> domain1.com 
>> domain2.org 
>> domain3.co.uk 
>> domain4.net 
+2

我同意! Pythons的字符串操作功能非常強大,我感覺自己的頭靠在牆上,而正則表達式通常是不需要的。我很少再使用'import re'。 – SethMMorton

4

你有一個捕獲組在你的表達。 re.findall文檔說明:

如果模式中存在一個或多個組,返回一組組列表;如果模式有多個組,這將是一個元組列表。

這就是爲什麼只返回捕獲組的內容。

嘗試:

re.findall("^.*((?:SLD|TLD)\d*)=(.*)$", enom, re.M) 

這將返回元組的列表:

[('SLD1', 'domain1'), ('TLD1', 'com'), ('SLD2', 'domain2'), ('TLD2', 'org'), ('SLD3', 'domain3'), ('TLD4', 'co.uk'), ('SLD5', 'domain4'), ('TLD5', 'net')] 

結合的SLD和頂級域名然後給你。

3

我不知道爲什麼你說的是正則表達式。我的意思是,你爲什麼不運行for循環?

一句名言似乎是適當的位置:

一些人,當遇到一個問題,認爲「我知道,我將使用 正則表達式。」現在他們有兩個問題。

domains = [] 
components = [] 
for line in enom.split('\n'): 
    k,v = line.split('=') 
    if k == 'TLDOverride': 
    continue 
    components.append(v) 
    if k.startswith('TLD'): 
    domains.append('.'.join(components)) 
    components = [] 

附:我不知道這是什麼TLDOverride所以代碼只是忽略它。

+0

我認爲這是最好的解決方案,因爲它是O(n)算法。 –

2

這裏有一種方法:

import re 
print map('.'.join, zip(*[iter(re.findall(r'^(?:S|T)LD\d+=(.*)$', text, re.M))]*2)) 
# ['domain1.com', 'domain2.org', 'domain3.co.uk', 'domain4.net'] 
1

您需要使用正則表達式多本。這與this post類似。

data = """SLD1=domain1 
TLD1=com 
SLD2=domain2 
TLD2=org 
TLDOverride=1 
SLD3=domain3 
TLD4=co.uk 
SLD5=domain4 
TLD5=net 
TLDOverride=1""" 

domain_seq = re.compile(r"SLD\d=(\w+)\nTLD\d=(\w+)", re.M) 
for item in domain_seq.finditer(data): 
    domain, tld = item.group(1), item.group(2) 
    print "%s.%s" % (domain,tld) 
2

只是爲了好玩,地圖 - >過濾器 - >圖:

input = """ 
SLD1=domain1 
TLD1=com 
SLD2=domain2 
TLD2=org 
TLDOverride=1 
SLD3=domain3 
TLD4=co.uk 
SLD5=domain4 
TLD5=net 
""" 

splited = map(lambda x: x.split("="), input.split()) 
slds = filter(lambda x: x[1][0].startswith('SLD'), enumerate(splited)) 
print map(lambda x: '.'.join([x[1][1], splited[x[0] + 1][1], ]), slds) 

>>> ['domain1.com', 'domain2.org', 'domain3.co.uk', 'domain4.net'] 
1

由於一些其他的答案已經說了,就沒有必要在這裏使用正則表達式。一個簡單的split和一些過濾將很好地做:

lines = data.split("\n") #assuming data contains your input string 
sld, tld = [[x.split("=")[1] for x in lines if x[:3] == t] for t in ("SLD", "TLD")] 
result = [x+y for x, y in zip(sld, tld)]