2010-11-18 29 views
0

我是新手到Python(数值本身的字符串)在给定的行,我面临着以下问题,请帮帮我:如何检索字段值使用正则表达式在Python

我从一个文件中读出一行行,具有字段名称和它的值的每一行, 现在我必须找出字段名称和filevalue一致的line.example是:

line=" A= 4 | B='567' |c=4|D='aaa' " 

由于某些字段值本身是一个字符串,所以我无法创建正则表达式来检索字段名称和字段值。

请让我知道上述例子的正则表达式。 输出应该是

A=4 

B='567' 

c=4 

D='aaa' 
+0

字符串是否可以包含引号或|标记? – 2010-11-18 09:34:27

+0

A = 4 | B ='567'| c = 4 | D ='aaa' – james 2010-11-18 10:02:30

+0

我有数据recodrd A = 4 | B ='567'| c = 4 | D ='aaa'在我正在逐行阅读的文件中 – james 2010-11-18 10:03:19

回答

0

试试这个:

import re 

line = " A= 4 | B='567' |c=4|D='aaa' " 
re.search('(?P<field1>.*)=(?P<value1>.*)\|(?P<field2>.*)=(?P<value2>.*)\|(?P<field3>.*)=(?P<value3>.*)\|(?P<field4>.*)=(?P<value4>.*)', line).groups() 

输出:

(' A', ' 4 ', ' B', "'567' ", 'c', '4', 'D', "'aaa' ") 

,你也可以尝试使用\ S *,而不是*如果你的字段和值做。不包含空格。这将消除输出的空格:

re.search('(?P<field1>\S*)\s*=\s*(?P<value1>\S*)\s*\|\s*(?P<field2>\S*)\s*=\s*(?P<value2>\S*)\s*\|\s*(?P<field3>\S*)\s*=\s*(?P<value3>\S*)\s*\|\s*(?P<field4>\S*)\s*=\s*(?P<value4>\S*)', line).groupdict() 

输出:

{'field1': 'A', 
'field2': 'B', 
'field3': 'c', 
'field4': 'D', 
'value1': '4', 
'value2': "'567'", 
'value3': '4', 
'value4': "'aaa'" 
} 

这将创建相关群体:

[ re.search('\s*([^=]+?)\s*=\s*(\S+)', group).groups() for group in re.findall('([^=|]*\s*=\s*[^|]*)', line) ] 

输出:

[('A', '4'), ('B', "'567'"), ('c', '4'), ('D', "'aaa'")] 

帮助?

+0

你不能在键和值之间建立链接,例如'A'与'4'无关 – 2010-11-18 12:14:43

0

假设你没有讨厌的东西像嵌套引用或不匹配的报价,你可以用splitstrip做这一切:

>>> line = " A= 4 | B='567' |c=4|D='aaa' " 
>>> values = dict((x.strip(" '"), y.strip(" '")) for x,y in (entry.split('=') for entry in line.split('|'))) 
>>> values 
{'A': '4', 'c': '4', 'B': '567', 'D': 'aaa'} 
+0

虽然我同意不一定需要一个正则表达式,恕我直言,这是一个相当复杂的表达,扔在一个Python新手你会不同意吗?无论如何,如果你限制你的代码行的长度,这将更容易让大家理解你的答案,所以滚动是不必要的阅读它 – martineau 2010-11-18 11:50:06

+0

你把数字当作字符串;根据问题,'c = 4'而不是'c ='4''。 – 2010-11-18 12:12:53

+0

@Adam Matan - 好点。你的答案解决了这个问题,所以我刚刚提出了这个问题。 – 2010-11-18 13:28:22

1

我能想到的最简单的办法是将每一行到字典中。我假设你的字符串中没有任何引号或|标记(请参阅我对问题的评论)。

result={}      # Initialize a dictionary 
for line in open('input.txt'): # Read file line by line in a memory-efficient way 
    # Split line to pairs using '|', split each pair using '=' 
    pairs = [pair.split('=') for pair in line.split('|')] 
    for pair in pairs: 
     key, value = pair[0].strip(), pair[1].strip() 
     try:      # Try an int conversion 
      value=int(value) 
     except:     # If fails, strip quotes 
      value=value.strip("'").strip('"') 
     result[key]=value  # Add current item to the results dictionary 

其中,以下输入:

A= 4 | B='567' |c=4|D='aaa' 
E= 4 | F='567' |G=4|D='aaa' 

还会送:

{'A': 4, 'c': 4, 'B': '567', 'E': 4, 'D': 'aaa', 'G': 4, 'F': '567'} 

注:

  • 如果考虑'567'是一个数字,你可以剥去"和尝试将其转换为整数之前,请使用'
  • 如果您需要考虑花车,您可以尝试value=float(value)。记住在int转换尝试后执行它,因为每个int都是浮点数。
+0

你没有使用正则表达式;根据问题,请让我知道上面的例子的正则表达式 – Matus 2010-11-24 14:14:41

+0

如果有更简单的Pythonic解决方案,为什么强制正则表达式? – 2010-11-28 17:53:05

+0

,因为它是在问题中。不知道他为什么要使用re。也许运动?我不判断问题,如果我知道答案,我会回答他们。 顺便说一句,你的解决方案并不比我认为的简单。 – Matus 2010-12-02 12:38:42

相关问题