Рэгулярны выраз у Python

Я спрабую стварыць спіс даменных імёнаў з API выкліку Enom. Я вярнуся шмат інфармацыі і трэба знайсці даменныя імёны, звязаныя з лініяй, а затым злучыць іх разам.

Радок, якая вяртаецца з 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) 
2

8 адказы

Edit: Every time I see a question asking for regular expression solution I have this bizarre urge to try and solve it without regular expressions. Most of the times it's more efficient than the use of regex, I encourage the OP to test which of the solutions is most efficient.

Вось просты падыход:

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
6
дададзена
Я згодзен! Пітоны маніпуляцыя радкі функцыя настолькі моцная, я адчуваю, удараючы лоб сцены з рэгулярным выразам часта непатрэбны. Я рэдка выкарыстоўваю імпарт паўторна больш.
дададзена аўтар SethMMorton, крыніца

У вас ёсць група захопу ў сваім выразе. re.findall дакументацыя кажа:

<�Р> Калі адна або некалькі груп, прысутнічаюць ва ўзоры, вяртае спіс груп; гэта будзе спіс картэжаў, калі ўзор мае больш за адну групы.

Вось чаму толькі conent групы захопу вяртаецца.

паспрабаваць:

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')]

Аб'яднанне УОС і дву тады да вас.

4
дададзена

гэта працуе для вас, напрыклад,

>>> 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']
3
дададзена

Я не ўпэўнены, чаму вы кажаце аб рэгулярных выразах. Я маю на ўвазе, чаму вы не проста запусціць для цыкл?

Вядомая цытата, здаецца, тут дарэчы:

<�Р> Некаторыя людзі, сутыкаючыся з праблемай, думаю, «Я ведаю, я буду выкарыстоўваць   рэгулярныя выразы «. Цяпер у іх ёсць дзве праблемы.
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 = []

P.S. Я не ўпэўнены, што гэта TLDOverride так што код проста ігнаруе яго.

3
дададзена
Я думаю, што гэта лепшае рашэнне, таму што гэта (п) алгарытм высновы.
дададзена аўтар Andrei Kaigorodov, крыніца

Вось адзін са спосабаў:

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']
2
дададзена

Just for fun, map -> filter -> map:

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']
2
дададзена

Вы павінны выкарыстоўваць шматрадковы рэгулярны выраз для гэтага. Гэта падобна на гэта паведамленне .

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)
1
дададзена

Як некаторыя іншыя адказы ўжо сказалі, няма неабходнасці выкарыстоўваць рэгулярны выраз тут. Просты Раскол і некаторыя фільтрацыі будуць рабіць прыгожа:

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)]
1
дададзена