从文本文件中使用REGEX在Python中提取变量名称和值
我想读取包含变量名称和相应值的大型文本文件(请参阅下面的小例子)。名称都是大写字母,值通常用句点和空白字符分隔,但如果变量名称太长,则它仅被空格分隔。从文本文件中使用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这样的东西,但我不能得到它的工作。 成功时,我想将数据存储在数据框中,变量名称为索引,值为列。
您可以使用下面的表达re.finditer()
一起:
(?P<category>[A-Z][A-Z- ]+[A-Z])
[. ]+
(?P<value>-?\d[.\d]+)\
(?P<unit>M|DEG|KN)
在
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-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-\/]+(?:\.)*)*
/是用于多个单词和/或其中包含句点的单词的捕获组
感谢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
@EmielT编辑我的回答 – depperm
如果您曾想要取出前导空白/尾部空白,则可以使用.strip()
方法。
stripped_values = [raw.strip() for raw in re.findall('(?<=\s.)[A-Z\s]+', line)]
使用'r'[A-Z] +(?:\ s + [A-Z] +)*'' –