从简单的文本文件中提取特定的文本部分
Extracting specific sections of text from simple text files
在 Python 方面,我是一个新手,正在努力完成以下任务。希望有人能帮忙。
我有大量文件具有一些共同特征,尽管不是全部。在这些文件中是我需要提取的信息部分,但只有那些包含特定文本行的部分。这是其中一个文件中常见文本的片段:
31 号房间
名字“鲍勃”
没有电视插座 49
退出
房间 5
名字“泰德”
服务省份 10.1
出口 49-50,52
退出
房间 80
名称“爱丽丝”
出口 49-50,52
死出口 1-20
退出
房间 50
名称“蒂姆”
出口 49
退出
51号房间
名称“苏”
服务提供 10.2.0
出口 49
退出
我想要输出的是任何包含“service prov”的部分(包括同一行上的任何其他文本)所以以上面为例,我需要的文本盯着“room 5”(数字可以变化)直到并包括“出口”,“51 号房间”也是如此 - 像这样:
房间 5
名字“泰德”
服务省份 10.1
出口 49-50,52
退出
51号房间
名称“苏”
服务提供 10.2.0
出口 49
退出
实现这一点的最简单方法是什么,请记住该部分中的行数可以变化并出现在原始文本文件中的任何位置?
非常感谢所有建议(尤其是简单的建议)!谢谢!
给定您问题中描述的表单的文本输入。以下是我的做法:
def parse_input(in_data):
start_key = 'room'
end_key = 'exit'
trigger_key = 'service prov'
new_element = False
trigger_exists = False
out_data = ''
element_data = ''
for line in in_data:
if not new_element and start_key == line[:len(start_key)].lower():
new_element = True
element_data += f'{line}\n'
else:
element_data += f'{line}\n'
if trigger_key == line[:len(trigger_key)].lower():
trigger_exists = True
if end_key == line[:len(end_key)].lower():
if trigger_exists:
out_data += element_data
trigger_exists = False
new_element = False
element_data = ''
return out_data
正在执行
print(parse_input(lines))
生产:
room 5
name "Ted"
service prov 10.1
outlet 49-50,52
exit
room 51
name "Sue"
service prov 10.2.0
outlet 49
exit
另一种选择可能是使用一种模式,从房间开始匹配到出口匹配结束,同时在两者之间匹配服务 prov。
^room \d+(?:\n(?!room \d|service prov).*)*\nservice prov.*(?:\n(?!room|exit).*)*\nexit$
模式匹配:
^room \d+
字符串开头,匹配 room
和 1+ 位
(?:\n(?!room \d|service prov).*)*
使用否定先行匹配所有不以房间和数字或服务 prov 开头的行 (?!
\nservice prov.*
匹配换行和整行服务证明
(?:\n(?!room|exit).*)*
使用否定先行匹配所有不以任一出口房间开头的行 (?!
\nexit$
匹配换行符,exit
并断言字符串结尾
例子
import re
regex = r"^room \d+(?:\n(?!room \d|service prov).*)*\nservice prov.*(?:\n(?!room|exit).*)*\nexit$"
test_str = ("room 31\n"
"name \"Bob\"\n"
"no TV outlet 49\n"
"exit\n"
"room 5\n"
"name \"Ted\"\n"
"service prov 10.1\n"
"outlet 49-50,52\n"
"exit\n"
"room 80\n"
"name \"Alice\"\n"
"outlet 49-50,52\n"
"dead outlet 1-20\n"
"exit\n"
"room 50\n"
"name \"Tim\"\n"
"outlet 49\n"
"exit\n"
"room 51\n"
"name \"Sue\"\n"
"service prov 10.2.0\n"
"outlet 49\n"
"exit")
print(re.findall(regex, test_str, re.MULTILINE))
输出
['room 5\nname "Ted"\nservice prov 10.1\noutlet 49-50,52\nexit', 'room 51\nname "Sue"\nservice prov 10.2.0\noutlet 49\nexit']
在 Python 方面,我是一个新手,正在努力完成以下任务。希望有人能帮忙。
我有大量文件具有一些共同特征,尽管不是全部。在这些文件中是我需要提取的信息部分,但只有那些包含特定文本行的部分。这是其中一个文件中常见文本的片段:
31 号房间
名字“鲍勃”
没有电视插座 49
退出
房间 5
名字“泰德”
服务省份 10.1
出口 49-50,52
退出
房间 80
名称“爱丽丝”
出口 49-50,52
死出口 1-20
退出
房间 50
名称“蒂姆”
出口 49
退出
51号房间
名称“苏”
服务提供 10.2.0
出口 49
退出
我想要输出的是任何包含“service prov”的部分(包括同一行上的任何其他文本)所以以上面为例,我需要的文本盯着“room 5”(数字可以变化)直到并包括“出口”,“51 号房间”也是如此 - 像这样:
房间 5
名字“泰德”
服务省份 10.1
出口 49-50,52
退出
51号房间
名称“苏”
服务提供 10.2.0
出口 49
退出
实现这一点的最简单方法是什么,请记住该部分中的行数可以变化并出现在原始文本文件中的任何位置?
非常感谢所有建议(尤其是简单的建议)!谢谢!
给定您问题中描述的表单的文本输入。以下是我的做法:
def parse_input(in_data):
start_key = 'room'
end_key = 'exit'
trigger_key = 'service prov'
new_element = False
trigger_exists = False
out_data = ''
element_data = ''
for line in in_data:
if not new_element and start_key == line[:len(start_key)].lower():
new_element = True
element_data += f'{line}\n'
else:
element_data += f'{line}\n'
if trigger_key == line[:len(trigger_key)].lower():
trigger_exists = True
if end_key == line[:len(end_key)].lower():
if trigger_exists:
out_data += element_data
trigger_exists = False
new_element = False
element_data = ''
return out_data
正在执行
print(parse_input(lines))
生产:
room 5
name "Ted"
service prov 10.1
outlet 49-50,52
exit
room 51
name "Sue"
service prov 10.2.0
outlet 49
exit
另一种选择可能是使用一种模式,从房间开始匹配到出口匹配结束,同时在两者之间匹配服务 prov。
^room \d+(?:\n(?!room \d|service prov).*)*\nservice prov.*(?:\n(?!room|exit).*)*\nexit$
模式匹配:
^room \d+
字符串开头,匹配room
和 1+ 位(?:\n(?!room \d|service prov).*)*
使用否定先行匹配所有不以房间和数字或服务 prov 开头的行(?!
\nservice prov.*
匹配换行和整行服务证明(?:\n(?!room|exit).*)*
使用否定先行匹配所有不以任一出口房间开头的行(?!
\nexit$
匹配换行符,exit
并断言字符串结尾
例子
import re
regex = r"^room \d+(?:\n(?!room \d|service prov).*)*\nservice prov.*(?:\n(?!room|exit).*)*\nexit$"
test_str = ("room 31\n"
"name \"Bob\"\n"
"no TV outlet 49\n"
"exit\n"
"room 5\n"
"name \"Ted\"\n"
"service prov 10.1\n"
"outlet 49-50,52\n"
"exit\n"
"room 80\n"
"name \"Alice\"\n"
"outlet 49-50,52\n"
"dead outlet 1-20\n"
"exit\n"
"room 50\n"
"name \"Tim\"\n"
"outlet 49\n"
"exit\n"
"room 51\n"
"name \"Sue\"\n"
"service prov 10.2.0\n"
"outlet 49\n"
"exit")
print(re.findall(regex, test_str, re.MULTILINE))
输出
['room 5\nname "Ted"\nservice prov 10.1\noutlet 49-50,52\nexit', 'room 51\nname "Sue"\nservice prov 10.2.0\noutlet 49\nexit']