繁体   English   中英

用Python匹配同一行的多个

[英]Matching multiple of the same line with Python

我正在尝试使用正则表达式匹配连续相似行的多个块。 准确地说,我正在尝试匹配文件中的多个块

H  0  0  0
O  0  0  1
H  0  1  1

它在文件中以不同的值多次出现(对于那些好奇的人,我正试图抓住由量子化学几何优化程序输出的分子几何)。

我尝试了一个正则表达式

import re
#                 atom      x       y       z
>>> my_re = r'(\s*(\w+)\s+(\d+)\s+(\d+)\s+(\d+)\n)+'
>>> my_string = 'lorem ipsum\nH 0 0 0\nO 0 0 1\nH 0 1 1\nlorem ipsum'
>>> re.findall(my_re, my_string)
[('H 0 1 1\n', 'H', '0', '1', '1')]

它不匹配整个分子块,而是仅匹配块的最后一行。 如果我删除最后的+ ,则正则表达式将分别匹配该块的所有行,即

[('H 0 0 0\n', 'H', '0', '0', '0'),
 ('O 0 0 1\n', 'O', '0', '0', '1'),
 ('H 0 1 1\n', 'H', '0', '1', '1')]

如果我复制了正则表达式,我很乐意匹配连续的行,例如

>>> re.findall(my_re*3, a)
[('H 0 0 0\n', 'H', '0', '0', '0',
  'O 0 0 1\n', 'O', '0', '0', '1',
  'H 0 1 1\n', 'H', '0', '1', '1')]

这给出了我想要的结果,但是,我不知道我需要提前匹配的块的长度。 如何修复正则表达式以匹配多个连续行?

您遇到的问题是Python的re模块不能很好地处理重复的组。 如果您有一个类似于"(foo)+"的模式并匹配"foofoofoo" ,则该模式将匹配整个字符串,但是只会捕获最后一个"foo"子字符串。

您可以通过几种方法解决此问题。 我的第一个想法是在没有任何捕获组的情况下进行第一次匹配,以便将整个块作为字符串获取,然后在每个块上重新进行匹配(带有捕获组)以分析各行的值:

block_re = r'(?:\s*\w+\s+\d+\s+\d+\s+\d+\n)+' # no groups, findall will yield strings
row_re = r'(\s*(\w+)\s+(\d+)\s+(\d+)\s+(\d+))' # you may not want the outer group here
results = [re.findall(row_re, block) for block in re.findall(block_re, my_string)]

results变量将是元组列表的列表,对应于块和其中的行。

解决它的另一种方法是使用更高级的正则表达式库。 我还没有任何亲身经历,但是我听说regex模块允许您重复分组并仍然获得所有捕获的结果。 我实际上并不知道它是如何工作的,因此,如果走这条路线,您将不得不阅读文档或进行一些试验。

暂无
暂无

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

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