繁体   English   中英

如何在 python 中的 multilne 字符串上使用正则表达式向后搜索

[英]How to search backwards with regex on multilne string in python

我想知道是否有一种有效的方法可以执行以下操作:

我有一个 python 脚本,可以将整个文件读入单个字符串。 然后,给定感兴趣的标记的位置,我想找到给定该标记的行开头的字符串索引。

file_str = read_file("foo.txt")
token_pos = re.search("token",file_str).start()

#this does not work, as str.rfind does not take regex, and you cannot specify re.M:
beginning_of_line = file_str.rfind("^",0,token_pos)

我可以使用贪婪的正则表达式来查找行的最后一个开头,但这必须多次完成,所以我担心我不想在每次迭代时读取整个文件。 有没有好的方法来做到这一点?

- - - - - - - - - 编辑 - - - - - - - -

我试图发布一个简单的问题,但看起来需要更多细节。 这是我正在尝试做的事情之一的更好示例:

file_str = """
{
   blah {  
      {} {{}  "string with unmatched }" }
   }
}"""

我碰巧知道blah的牙套的开闭位置在哪里。 我需要得到大括号之间的线条(不包括在内)。 因此,给定右大括号的 position,我需要找到包含它的行的开头。 我想做一些类似于反向正则表达式的事情来找到它。 当然,我可以编写一个特殊的 function 来执行此操作,但我认为会有更多类似 python 的方法来处理它。 更复杂的是,我必须为每个文件执行多次此操作,并且文件字符串可能会在迭代之间发生变化,因此预索引也不起作用......

不要只匹配关键字,而是匹配从行首到关键字的所有内容 您可以使用re.finditer()文档来获取一个迭代器,该迭代器在找到匹配项时不断产生匹配项。

file_str = """Lorem ipsum dolor sit amet, consectetur adipiscing elit amet.
Vestibulum vestibulum mollis enim, eu tristique est rhoncus et.
Curabitur sem nisi, ornare eu pellentesque at, interdum at lectus.
Phasellus molestie, turpis id ornare efficitur, ex tellus aliquet ipsum, vitae ullamcorper tellus diam a velit.
Nulla eget eleifend nisl.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Nullam finibus, velit non euismod faucibus, dolor orci maximus lacus, sed mattis nisi erat eget turpis.
Maecenas ut pharetra lorem.
Curabitur nec dui sed velit euismod bibendum.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Pellentesque tempor dolor at placerat aliquet.
Duis laoreet, est vitae tempor porta, risus leo ullamcorper risus, quis vestibulum massa orci ut felis.
In finibus purus ac nulla congue mattis.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Duis efficitur dui ac nisi lobortis, a bibendum felis volutpat.
Aenean consectetur diam at risus hendrerit, in vestibulum erat porttitor.
Quisque fringilla accumsan neque, sed efficitur nunc tristique maximus.
Maecenas gravida lectus et porttitor ultrices.
Nam lobortis, massa et porta vulputate, nulla turpis maximus sapien, sit amet finibus libero mauris eu sapien.
Donec sollicitudin vulputate neque, in tempor nisi suscipit quis.
"""

keyword = "amet"
for match_obj in re.finditer(f"^.*{keyword}", file_str, re.MULTILINE):
    beginning_of_line = match_obj.start()
    print(beginning_of_line, match_obj)

这使:

0 <re.Match object; span=(0, 60), match='Lorem ipsum dolor sit amet, consectetur adipiscin>
331 <re.Match object; span=(331, 357), match='Lorem ipsum dolor sit amet'>
566 <re.Match object; span=(566, 592), match='Lorem ipsum dolor sit amet'>
815 <re.Match object; span=(815, 841), match='Lorem ipsum dolor sit amet'>
1129 <re.Match object; span=(1129, 1206), match='Nam lobortis, massa et porta vulputate, nulla tur>

请注意,第一行仅匹配一次,即使它包含两个amet ,因为我们对 进行了贪婪匹配. 所以线上的第一个amet.*消耗了

您不需要使用正则表达式来查找带有令牌的行的开头

这将逐行迭代文件,使用文件内容创建字符串 foo 并记录换行符在名为 line_pos_with_token 的列表中的位置

token = "token"
foo = ''
line_pos_with_token = []

with open("foo.txt", "r") as f:
    for line in f:
        if token in line:
            line_pos_with_token.append(len(foo))
        foo += line

print(line_pos_with_token)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM