如何在列表长度发生变化时从列表中提取特定单词?

时间:2016-07-25 14:29:45

标签: python string parsing

我们假设我有以下字符串的示例:

  • string ='http / 1.1 abc-ad-sd-00 .sad.sdsd.der.net(Server / 1.2 [dsddsf did:t yy p sS]),http / 1.1 < strong> asc-ad-sd-11 .sad.sdsd.der.net(Server / 1.2 [ gfef srFw:t reri pSs ])'
  • string1 ='http / 1.1 abc-ad-sd-01 .sad.sdsd.der.net(Server / 1.2 [dsddsf fu did:t yy p sS]),http / 1.1 asc-ad-sd-13 .sad.sdsd.der.net(Server / 1.2 [ sff as srFw:t reri pSs ])'
  • string2 ='http / 1.1 abc-ad-sd-002 .sad.sdsd.der.net(Server / 1.2 [dsddsf did:t yy p sS]),http / 1.1 < strong> asc-ad-sd-14 .sad.sdsd.der.net(Server / 1.2 [ rts as f srFw:t reri pSs ])'
  • string3 ='http / 1.1 abc-ad-sd-03 .sad.sdsd.der.net(Server / 1.2 [dsddsf did:t yy p sS]),http / 1.1 < strong> asc-ad-sd-15 .sad.sdsd.der.net(Server / 1.2 [ tttts as t srFw:t reri pSs ])'

以下是我为获得大胆字符串所做的工作:

If name == 'via':

name = “ID1”
string = header_line.split(' ')
b = (string[2].split('.'))
value = b[0]
headers[name] = value

#----------#

name_1 = “ID2”
string = header_line.split(' ')
b_1 = (string[9].split('.'))
value_1 = b_1[0]
headers[name_1] = value_1

#-----#

name_2 = “ID3”
string = header_line.split(' ')
b_2 = (string[11:])
value_2 = ''.join(b_2)
headers[name_2] = value_2

#----#

这个问题是它只适用于某些情况。正如您所看到的,有3个不同的字符串,因此通过索引获取粗体字符串并不是很有效。当然,这不是我的完整代码,因为这些字符串存储在dict列表中。 例: 我的初始输出如下所示:

  

[{'item1':'10574','Item2':'69 .241.51.134','via':'http / 1.1 abc-ad-sd-00.sad.sdsd.der.net(Server / 1.2 [dsddsf做了:t yy p sS]),http / 1.1 asc-ad-sd-11.sad.sdsd.der.net(Server / 1.2 [tttts srFw:t reri pSs]))','item4':' 22','HTTP RESPONSE':['HTTP / 1.1 200 OK \ r \ n']},{...},{...}]

我希望根据上面的响应中的解析值,输出不同的输出。

  

[{'item1':'10574','Item2':'69 .241.51.134','ID3':'tttts srFw:t reri pSs','item4':'22','ID2':'asc -ad-sd-11','HTTP RESPONSE':['HTTP / 1.1 200 OK \ r \ n'],'ID1':'abc-ad-sd-00'},{...},{...}]

正如你所看到的,我在列表中有一堆dicts,而对于'via'键,我希望将它的值解析为我想要的不同子串并将它们存储到新的键值中。我已经在我的代码中完成了这个。

更新:感谢大家的回复。我澄清了我的问题。根据您的响应,ID1和ID2的值有效,但[]内的值不起作用,因为“tttts”在每个响应中都不是相同的字符串。

另一个更新: 感谢大家的帮助!!使用每个人的回复,我稍微调整了我的代码并找出了如何获取值。

5 个答案:

答案 0 :(得分:0)

我认为正则表达式是你的朋友。 http\/1\.1 ([^\.]+)之类的东西适用于这种特定情况。

import re
match = re.compile('http\/1\.1 ([^\.]+)').search(string)
value = match.group(1)

我建议使用string.split(',')分割字符串,或者分割每个http条目的工作。

您可以了解有关python的正则表达式模块here的更多信息,您可以在各种网站中测试我们的正则表达式,我喜欢this one.

答案 1 :(得分:0)

在我看来,您可以使用正则表达式来获取子字符串。

import re
pattern1 = r'\w+-\w+-\w+-\d+'
pattern2 = r'\[tttts .+\]'

#s is string you are checking
#pattern 1 will find substring like abc-ad-sd-00
re.findall(pattern1,s)
#pattern 2 will find substring like [tttts as t srFw:t reri pSs ]
re.findall(pattern2,s)

示例:

s = 'http/1.1 abc-ad-sd-00.sad.sdsd.der.net (Server/1.2 [dsddsf did:t yy p sS]), http/1.1 asc-ad-sd-11.sad.sdsd.der.net (Server/1.2 [tttts srFw:t reri pSs ])'

re.findall(r'\[tttts .+\]',s)
['[tttts srFw:t reri pSs ]']
re.findall(r'\w+-\w+-\w+-\d+',s)
['abc-ad-sd-00', 'asc-ad-sd-11']

答案 2 :(得分:0)

当您处理大量文本时,首先要做的是在字符串上使用/创建一个有效的内存友好迭代器。 (我们假设您将其放入函数line_iterator中)

要做的第二件事是使用正则表达式来获取字符串的必需部分(假设您编写并编译了正则表达式)。如果每个字符串中总是有2个相似的部分,请将它们放入正则表达式中的组中。

然后你可以这样做:

import re

regexp = re.compile('<you regular expression>')

for line in line_iterator():
    match = regexp.match(line)
    if match:
        write_to_csv(match.groups())

无论如何,看看regular expressions,它们是值得的

注意: 1.如果你需要经常使用它,请编译你的正则表达式; 2.使用生成器迭代字符串,不要将所有内容保存在内存中; 3.如果可以的话,最好使用1个正则表达式

答案 3 :(得分:0)

结帐positive lookbehind regular expression

import re

p = """string = 'http/1.1 abc-ad-sd-00.sad.sdsd.der.net (Server/1.2 [dsddsf did:t yy p sS]), http/1.1 asc-ad-sd-11.sad.sdsd.der.net (Server/1.2 [tttts srFw:t reri pSs ])'
string1 = 'http/1.1 abc-ad-sd-01.sad.sdsd.der.net (Server/1.2 [dsddsf f u did:t yy p sS]), http/1.1 asc-ad-sd-13.sad.sdsd.der.net (Server/1.2 [tttts as srFw:t reri pSs ])'
string2 = 'http/1.1 abc-ad-sd-002.sad.sdsd.der.net (Server/1.2 [dsddsf did:t yy p sS]), http/1.1 asc-ad-sd-14.sad.sdsd.der.net (Server/1.2 [tttts as f srFw:t reri pSs ])'
string3 = 'http/1.1 abc-ad-sd-03.sad.sdsd.der.net (Server/1.2 [dsddsf did:t yy p sS]), http/1.1 asc-ad-sd-15.sad.sdsd.der.net (Server/1.2 [tttts as t srFw:t reri pSs ])'
"""
s = re.findall("(?<=http/1.1\s)([\w\d\-]*)", p, re.DOTALL | re.MULTILINE)
s2 = re.findall("(?<=Server/1.2\s)\[([\w:\s]*)\]", p, re.DOTALL | re.MULTILINE)
print(list(s))
print(list(s2))

# will prints
# ['abc-ad-sd-00', 'asc-ad-sd-11', 'abc-ad-sd-01', 'asc-ad-sd-13', 'abc-ad-sd-002', 'asc-ad-sd-14', 'abc-ad-sd-03', 'asc-ad-sd-15']

# and
# ['dsddsf did:t yy p sS', 'tttts srFw:t reri pSs ', 'dsddsf f u did:t yy p sS', 'tttts as srFw:t reri pSs ', 'dsddsf did:t yy p sS', 'tttts as f srFw:t reri pSs ', 'dsddsf did:t yy p sS', 'tttts as t srFw:t reri pSs ']

答案 4 :(得分:0)

使用正则表达式,您可以在循环之前编译表达式,并在循环遍历每个字符串时获取所需的每个ID。第一个正则表达式将获得具有相同格式的前两个id。 \w+查找至少一个字,\d+查找至少一个数字。第二个表达式希望第二次出现括号中的内容,以便从\[.*?开始,然后在表达式的其余部分之前查找至少一个单词和一个空格。

import re

list_of_strings=[
    'http/1.1 abc-ad-sd-00.sad.sdsd.der.net (Server/1.2 [dsddsf did:t yy p sS]), http/1.1 asc-ad-sd-11.sad.sdsd.der.net (Server/1.2 [gfef srFw:t reri pSs ])',
    'http/1.1 abc-ad-sd-01.sad.sdsd.der.net (Server/1.2 [dsddsf f u did:t yy p sS]), http/1.1 asc-ad-sd-13.sad.sdsd.der.net (Server/1.2 [sff as srFw:t reri pSs ])',
    'http/1.1 abc-ad-sd-002.sad.sdsd.der.net (Server/1.2 [dsddsf did:t yy p sS]), http/1.1 asc-ad-sd-14.sad.sdsd.der.net (Server/1.2 [rts as f srFw:t reri pSs ])',
    'http/1.1 abc-ad-sd-03.sad.sdsd.der.net (Server/1.2 [dsddsf did:t yy p sS]), http/1.1 asc-ad-sd-15.sad.sdsd.der.net (Server/1.2 [tttts as t srFw:t reri pSs ])'
    ]

first_ids=r'\w+-\w+-\w+-\d+'
last_id=r'\[.*\[(\w+\s.*\w+:\w+\s\w+\s\w+)'
for url in list_of_strings:
    print(url)
    print(re.findall(first_ids,url)[0])
    print(re.findall(first_ids,url)[1])
    print(re.findall(last_id,url)[0])