2016-08-23 115 views
1

我想讀取包含變量名稱和相應值的大型文本文件(請參閱下面的小例子)。名稱都是大寫字母,值通常用句點和空白字符分隔,但如果變量名稱太長,則它僅被空格分隔。從文本文件中使用REGEX在Python中提取變量名稱和值

WATER DEPTH ..........  20.00 M  TENSION AT TOUCHDOWN . 382.47 KN 

TOUCHDOWN X-COORD. ... -206.75 M  BOTTOM SLOPE ANGLE ...  0.000 DEG 

PROJECTED SPAN LENGTH  166.74 M  PIPE LENGTH GAIN .....  1.72 M 

我可以使用下面的表達式查找值:

line = ' PROJECTED SPAN LENGTH  166.74 M  PIPE LENGTH GAIN .....  1.72 M \n' 
re.findall(r"[-+]?\d*\.\d+|\d+", line): 
['166.74', '1.72'] 

但是,當我嘗試提取變量名稱,使用以下的表達式我已經開頭和結尾的空格,我想忽略。

re.findall('(?<=\s.)[A-Z\s]+', line) 
[' PROJECTED SPAN LENGTH  ', '  PIPE LENGTH GAIN ', ' ', ' \n'] 

我相信它應該有^ \ s這樣的東西,但我不能得到它的工作。 成功時,我想將數據存儲在數據框中,變量名稱爲索引,值爲列。

+2

使用'r'[A-Z] +(?:\ s + [A-Z] +)*'' –

回答

0

您可以使用下面的表達re.finditer()一起:

(?P<category>[A-Z][A-Z- ]+[A-Z]) 
[. ]+ 
(?P<value>-?\d[.\d]+)\ 
(?P<unit>M|DEG|KN) 

a demo on regex101.com


Python這將是:

import re 

rx = re.compile(r''' 
    (?P<category>[A-Z][A-Z- ]+[A-Z]) 
    [. ]+ 
    (?P<value>-?\d[.\d]+)\ 
    (?P<unit>M|DEG|KN) 
''', re.VERBOSE) 

string = ''' 
WATER DEPTH ..........  20.00 M  TENSION AT TOUCHDOWN . 382.47 KN 

TOUCHDOWN X-COORD. ... -206.75 M  BOTTOM SLOPE ANGLE ...  0.000 DEG 

PROJECTED SPAN LENGTH  166.74 M  PIPE LENGTH GAIN .....  1.72 M 
''' 

matches = [(m.group('category'), m.group('value'), m.group('unit')) \ 
      for m in rx.finditer(string)] 
print(matches) 
# [('WATER DEPTH', '20.00', 'M'), ('TENSION AT TOUCHDOWN', '382.47', 'KN'), ('TOUCHDOWN X-COORD', '-206.75', 'M'), ('BOTTOM SLOPE ANGLE', '0.000', 'DEG'), ('PROJECTED SPAN LENGTH', '166.74', 'M'), ('PIPE LENGTH GAIN', '1.72', 'M')] 

a demo on ideone.com

+0

謝謝Jan,這是一個非常整潔的解決方案,regex101.com也非常方便。因此,我冒昧地向你提出另一個問題,我希望給出問題的鏈接[link] https://regex101.com/r/nK3hN6/1在我之前的問題中,我只發佈了一部分要分析的文字,但還有一些線條,我也有一些困難。例如,沒有單位的線路。在此先感謝 – EmielT

+0

@EmielT:https://regex101.com/r/nK3hN6/2(使最後一組可選,並把最長的替代方案先。 – Jan

+0

完美,非常感謝!它給了我至少更多的洞察力正則表達式。 – EmielT

0

使用[A-Z]{2,}(?:\s+[A-Z]+)*

[A-Z]{2,}查找大寫單詞至少2在長度

(?:\s+[A-Z]+)*爲如果在該標籤的多個詞的捕獲組

EDIT

要在你的評論中處理案例我推薦:

[A-Z-\/]{2,}(?:\s*[A-Z-\/]+(?:\.)*)* 

只要確保至少有一個空間在R.O.W.最後一期後前...

[A-Z-\/]{2,}將檢查大寫字母, - ,和2長度或更大

(?:\s*[A-Z-\/]+(?:\.)*)* /是用於多個單詞和/或其中包含句點的單詞的捕獲組

+0

感謝depperm,這個工作得很好。但是,對於最後一行_TOUCHDOWN X-COORD._正在分割爲_TOUCHDOWN_和_COORD_。好的,這可以通過轉義非捕獲組中的字符來解決。但是在文本文件中也可能會出現以下情況:空氣中的重量/長度。 1301。00 N/M屈服應力......... 241.00 MPA或BARGE HEADING ........ 0.000°OFF。 ... 0.00 M.這裏R.O.W.例如沒有找到,我相信可以通過使用lookbehind/lookahead語句來捕獲。你能否就如何實現這一點提供建議?謝謝 – EmielT

+0

@EmielT編輯我的回答 – depperm

0

如果您曾想要取出前導空白/尾部空白,則可以使用.strip()方法。

Python String strip

stripped_values = [raw.strip() for raw in re.findall('(?<=\s.)[A-Z\s]+', line)] 
相關問題