python正则表达式查找匹配字符串
我试图在Python中使用正则表达式在字符串中查找匹配的字符串。python正则表达式查找匹配字符串,python,regex,Python,Regex,我试图在Python中使用正则表达式在字符串中查找匹配的字符串。字符串如下所示: band 1 # energy -53.15719532 # occ. 2.00000000 ion s p d tot 1 0.000 0.995 0.000 0.995 2 0.000 0.000 0.000 0.000 tot 0.000 0.996 0.000 0.996 band 2 # energy -53.15719
字符串
如下所示:
band 1 # energy -53.15719532 # occ. 2.00000000
ion s p d tot
1 0.000 0.995 0.000 0.995
2 0.000 0.000 0.000 0.000
tot 0.000 0.996 0.000 0.996
band 2 # energy -53.15719532 # occ. 2.00000000
ion s p d tot
1 0.000 0.995 0.000 0.995
2 0.000 0.000 0.000 0.000
tot 0.000 0.996 0.000 0.996
band 3 # energy -53.15719532 # occ. 2.00000000
我的目标是在tot
之后找到字符串。因此,匹配的字符串将类似于:
['0.000 0.996 0.000 0.996',
'0.000 0.996 0.000 0.996']
这是我目前的代码:
pattern = re.compile(r'tot\s+(.*?)\n', re.DOTALL)
pattern.findall(string)
但是,输出给了我:
['1 0.000 0.995 0.000 0.995',
'0.000 0.996 0.000 0.996',
'1 0.000 0.995 0.000 0.995',
'0.000 0.996 0.000 0.996']
你知道我做错了什么吗?你不想要
DOTALL
标志。取下它,改用它
这将匹配以tot
开头的所有行。该行的其余部分将在第1组中
引用我的重点:
re.DOTALL
使“.
特殊字符与所有字符匹配,包括
新行;如果没有此标志,。
将匹配除
新线
请注意,在没有正则表达式的情况下,您可以轻松地执行此操作
with open("input.txt", "r") as data_file:
for line in data_file:
items = filter(None, line.split(" "))
if items[0] == "tot":
# etc
您不需要
DOTALL
标志。取下它,改用它
这将匹配以tot
开头的所有行。该行的其余部分将在第1组中
引用我的重点:
re.DOTALL
使“.
特殊字符与所有字符匹配,包括
新行;如果没有此标志,。
将匹配除
新线
请注意,在没有正则表达式的情况下,您可以轻松地执行此操作
with open("input.txt", "r") as data_file:
for line in data_file:
items = filter(None, line.split(" "))
if items[0] == "tot":
# etc
您使用的是re.DOTALL,这意味着点“.”将匹配任何内容,甚至是换行符,本质上是查找“tot”-s以及下一个换行符之前的所有内容:
tot
1 0.000 0.995 0.000 0.995
及
删除re.DOTALL应该可以解决您的问题
编辑:
实际上,DOTALL标志并不是真正的问题(尽管没有必要)。模式中的问题是\s+与换行符匹配。将其替换为单个空间可以解决此问题:
pattern = re.compile(r'tot (.*?)\n')
您使用的是re.DOTALL,这意味着点“.”将匹配任何内容,甚至是换行符,本质上是查找“tot”-s以及下一个换行符之前的所有内容:
tot
1 0.000 0.995 0.000 0.995
及
删除re.DOTALL应该可以解决您的问题
编辑:
实际上,DOTALL标志并不是真正的问题(尽管没有必要)。模式中的问题是\s+与换行符匹配。将其替换为单个空间可以解决此问题:
pattern = re.compile(r'tot (.*?)\n')
使用具有特定正则表达式模式的
re.findall
函数的替代解决方案:
# str is your inital string
result = re.findall('tot [0-9 .]+(?=\n|$)', str)
print(result)
输出:
['tot 0.000 0.996 0.000 0.996', 'tot 0.000 0.996 0.000 0.996']
使用具有特定正则表达式模式的
re.findall
函数的替代解决方案:
# str is your inital string
result = re.findall('tot [0-9 .]+(?=\n|$)', str)
print(result)
输出:
['tot 0.000 0.996 0.000 0.996', 'tot 0.000 0.996 0.000 0.996']
我想我应该将
DOTALL
更改为MULTILINE
,因为这里不需要@Tomalak suggestedMULTILINE,除非您希望使用^和$分别匹配行首和行尾。我必须指出@Tomalak的解决方案更干净。你说得对<代码>\s+实际上是这里的问题。我想它只意味着不止一个空格。谢谢你让我知道。我想我应该把DOTALL
改为MULTILINE
,因为这里不需要@Tomalak suggestedMULTILINE,除非你想分别使用^和$来匹配行首和行尾。我必须指出@Tomalak的解决方案更干净。你说得对<代码>\s+实际上是这里的问题。我想它只意味着不止一个空格。谢谢你让我知道。这解决了我的问题。我想我对DOTALL
和multiline
感到困惑。需要更多地了解它。这解决了我的问题。我想我对DOTALL
和multiline
感到困惑。需要更多地了解它。