首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从简单文本文件中提取特定的文本部分

从简单文本文件中提取特定的文本部分
EN

Stack Overflow用户
提问于 2021-04-19 11:59:15
回答 2查看 221关注 0票数 1

在Python方面,我是个新手,我正在努力完成以下任务。希望有人能帮忙。

我有大量的文件,它们有一些共同的特性,尽管不是全部。在这些文件中有一些我需要提取的信息,但只有那些包含特定文本行的部分。这是其中一个文件中常见文本的片段:

31室

取名“鲍勃”

无电视插座49

出口

第5室

名为"Ted“

服务程序10.1

出口49-50,52

出口

80室

取名为“爱丽丝”

出口49-50,52

死出口1-20

出口

50室

命名为"Tim“

出口49

出口

51室

名“苏”

服务prov 10.2.0

出口49

出口

我要输出的是包含"service prov“的任何部分(包括同一行中的任何其他文本),因此,以上面的示例为例,我需要”5房间“的文本(数字可能会有所变化),直到并包括"exit",对于”51房“,也是如此--如下所示:

第5室

名为"Ted“

服务程序10.1

出口49-50,52

出口

51室

名“苏”

服务prov 10.2.0

出口49

出口

要做到这一点,最简单的方法是什么,考虑到节中的行数可以变化,并出现在原始文本文件中的任何位置?

所有的建议(尤其是简单的)都非常感谢!谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-04-19 17:30:10

给出你问题中所描述的表格的文本输入。我会这样做:

代码语言:javascript
复制
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   

执行

代码语言:javascript
复制
print(parse_input(lines)) 

生产:

代码语言:javascript
复制
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
票数 1
EN

Stack Overflow用户

发布于 2021-04-19 18:54:10

另一种选择可以是使用模式,从房间开始匹配,结束匹配与出口匹配,而在两者之间匹配服务prov。

代码语言:javascript
复制
^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和断言字符串的结尾

示例

代码语言:javascript
复制
import re
 
regex = r"^room \d+(?:\n(?!room \d|service prov).*)*\nservice prov.*(?:\n(?!room|exit).*)*\nexit$"

Regex演示 x- Python演示

代码语言:javascript
复制
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))

输出

代码语言:javascript
复制
['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']
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67161599

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档