2010-11-18 56 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