python:提取匹配模式的更好方法?
我有如下代码。它在文件中的每一行搜索一些模式,如果找到,则从匹配的模式中提取一些字符串。每条线最多只能匹配一种图案(如果有)。文件中只有文本行,有些行有hight=123,有些中等=123,有些低=123python:提取匹配模式的更好方法?,python,Python,我有如下代码。它在文件中的每一行搜索一些模式,如果找到,则从匹配的模式中提取一些字符串。每条线最多只能匹配一种图案(如果有)。文件中只有文本行,有些行有hight=123,有些中等=123,有些低=123 with open(file) as r: for line in r: if re.search('high=\d+', line): p = re.search('high=(\d+)', line) high =
with open(file) as r:
for line in r:
if re.search('high=\d+', line):
p = re.search('high=(\d+)', line)
high = p.group(1)
elif re.search('medium=\d+', line):
p = re.search('medium=(\d+)', line)
medium = p.group(1)
elif re.search('low=\d+', line):
p = re.search('low=(\d+)', line)
low = p.group(1)
...
现在我想知道我是否可以在不进行第二次搜索的情况下提取匹配的部分,如下面以一些无效代码为例所示。搜索到的模式可能彼此非常不同。这里的问题是,在re.search返回true后,是否有方法提取匹配的部分
with open(file) as r:
for line in r:
if re.search('high=(\d+)', line):
high = _.group(1) # invalid code, but looking for something like this.
elif re.search('medium=(\d+)', line):
medium = _.group(1) # invalid code
elif re.search('low=(\d+)', line):
low = _.group(1) # invalid code
...
注:我本可以做到以下几点,但这不是我想要的
with open(file) as r:
for line in r:
m = re.search('high=(\d+)', line)
if m:
high = m.group(1)
else:
m = re.search('medium=(\d+)', line)
if m:
medium = m.group(1)
else:
m = re.search('low=(\d+)', line)
if m:
low = m.group(1)
...
我曾尝试先编译模式,如下面所示,但我得到了错误NameError:name'\ux'未定义。我用蟒蛇2和蟒蛇3都试过了。组1有一些特殊的行为。它在某些情况下起作用。我可以在另一篇文章中提出这个问题
h = re.compile('hight=(\d+)')
m = re.compile('medium=(\d+)')
l = re.compile('low=(\d+)')
with open(file) as r:
for line in r:
if h.search(line):
high = _.group(1)
elif m.search(line):
medium = _.group(1)
elif l.search(line):
low = _.group(1)
...
你可以试试这个
import re
r = re.compile("(high|medium|low)=(\d+)")
with open(file) as f:
for line in f:
match = r.search(line)
if not match:
continue
lvl, val = match.groups()
if lvl == "high":
high = val
elif lvl == "medium":
medium = val
elif lvl == "low":
low = val
你可以试试这个
import re
r = re.compile("(high|medium|low)=(\d+)")
with open(file) as f:
for line in f:
match = r.search(line)
if not match:
continue
lvl, val = match.groups()
if lvl == "high":
high = val
elif lvl == "medium":
medium = val
elif lvl == "low":
low = val
_保存在交互式shell中工作时最后执行的语句的结果。它只是程序上下文中的一个普通变量 因此,如果您不想再次执行搜索,您必须存储匹配对象,就像您在第三个代码示例中所做的那样 如果要避免嵌套ifs,可以使用“继续”:
with open(file) as r:
for line in r:
m = re.search('high=(\d+)', line)
if m:
high = m.group(1)
continue
m = re.search('medium=(\d+)', line)
if m:
medium = m.group(1)
continue
m = re.search('low=(\d+)', line)
if m:
low = m.group(1)
continue
...
编辑,以回答您的评论:
在Python中没有通用的方法来实现您想要的功能:
您没有任何自动将结果赋值给变量的功能,就像在Perl中一样
你不会写字
如果xxx=yyy:
避免书写错误,而不是==
不过,总有一种方法可以做到这一点:
import re
class Matcher:
def __init__(self, pattern):
self._pattern = pattern
self._compiled_pattern = re.compile(pattern)
self._match = None
def __str__(self):
return '<Matcher> %s, matching %s' % (self._pattern, self._match)
# match and search apply on the regex, and return the match object
def match(self, string):
self._match = self._compiled_pattern.match(string)
return self._match
def search(self, string):
self._match = self._compiled_pattern.search(string)
return self._match
# Other methods apply to the match object
def __getattr__(self, attr):
return getattr(self._match, attr)
if __name__ == '__main__':
# instead of m = re.compile(...)
m = Matcher(r'(high)=(\d+)')
lines = ['high=4', 'nothing here']
for line in lines:
# you can use search and match just like on the re object
if m.search(line):
# then you can use all methods of Match objects
print(m.groups())
print(m.group(1), m.group(2))
print(m.span())
所以,它看起来就像你想要的那样 \保存在交互式shell中工作时最后执行的语句的结果。它只是程序上下文中的一个普通变量 因此,如果您不想再次执行搜索,您必须存储匹配对象,就像您在第三个代码示例中所做的那样 如果要避免嵌套ifs,可以使用“继续”:
with open(file) as r:
for line in r:
m = re.search('high=(\d+)', line)
if m:
high = m.group(1)
continue
m = re.search('medium=(\d+)', line)
if m:
medium = m.group(1)
continue
m = re.search('low=(\d+)', line)
if m:
low = m.group(1)
continue
...
编辑,以回答您的评论:
在Python中没有通用的方法来实现您想要的功能:
您没有任何自动将结果赋值给变量的功能,就像在Perl中一样
你不会写字
如果xxx=yyy:
避免书写错误,而不是==
不过,总有一种方法可以做到这一点:
import re
class Matcher:
def __init__(self, pattern):
self._pattern = pattern
self._compiled_pattern = re.compile(pattern)
self._match = None
def __str__(self):
return '<Matcher> %s, matching %s' % (self._pattern, self._match)
# match and search apply on the regex, and return the match object
def match(self, string):
self._match = self._compiled_pattern.match(string)
return self._match
def search(self, string):
self._match = self._compiled_pattern.search(string)
return self._match
# Other methods apply to the match object
def __getattr__(self, attr):
return getattr(self._match, attr)
if __name__ == '__main__':
# instead of m = re.compile(...)
m = Matcher(r'(high)=(\d+)')
lines = ['high=4', 'nothing here']
for line in lines:
# you can use search and match just like on the re object
if m.search(line):
# then you can use all methods of Match objects
print(m.groups())
print(m.group(1), m.group(2))
print(m.span())
所以,它看起来就像你想要的那样 如果你能给出一个输入的例子,以及你期望从中产生什么,那会很有帮助。@Naktini谢谢。我补充了一些解释。其实问题很简单。在re.search返回true后,是否有方法获取匹配模式的部分内容,不管它是什么?Perl允许您将匹配的部分保存在一个全局变量中。Python没有自动分配给全局变量。您可以很容易地编写一个包装器函数来完成它,但它并没有内置到语言中。@JohnY谢谢。知道Python只是缺少这样的特性也是件好事。因此,我将重点介绍其他内容。如果您能给出一个输入示例以及您希望从中生成的内容,这将有所帮助。@Naktini谢谢。我补充了一些解释。其实问题很简单。在re.search返回true后,是否有方法获取匹配模式的部分内容,不管它是什么?Perl允许您将匹配的部分保存在一个全局变量中。Python没有自动分配给全局变量。您可以很容易地编写一个包装器函数来完成它,但它并没有内置到语言中。@JohnY谢谢。知道Python只是缺少这样的特性也是件好事。所以我会关注其他事情。谢谢。你发布的内容应该适用于我在代码中显示的案例。但我要寻找的是一种更通用的方法,在re.search返回true后提取匹配的模式,而不必测试任何其他内容。@shipping re.search返回匹配对象,而不是布尔值。即使将匹配替换为搜索,上述代码也可以工作。如果要测试然后提取,可以执行try.。除了上面相同的代码外,也可以指定通过re.search返回的匹配对象,并检查它是否为“无”。@adifire-我认为您的编辑与OP所要查找的内容没有任何关系。事实上,情况可能更糟。在主要问题处查看他们对Perl的评论。@JohnY我想你是对的,也许我这里遗漏了什么。我认为在输入的情况下,代码应该可以正常工作。谢谢。你发布的内容应该适用于我在代码中显示的案例。但我要寻找的是一种更通用的方法,在re.search返回true后提取匹配的模式,而不必测试任何其他内容。@shipping re.search返回匹配对象,而不是布尔值。即使将匹配替换为搜索,上述代码也可以工作。如果您想测试然后提取,除了上面的相同代码之外,您可以尝试
或者指定通过re.search返回的匹配对象,并检查它是否为“无”。@adifire-我认为您的编辑与OP要查找的内容没有任何相似之处。事实上,情况可能更糟。在主要问题处查看他们对Perl的评论。@JohnY我想你是对的,也许我这里遗漏了什么。我认为在输入的情况下,代码应该可以正常工作。谢谢。这当然有效。但我想知道是否有替代方案,如第二个代码示例所示。显然Python缺少这样的功能。@shipping-Python缺少这个功能,但是自己添加它很简单。这里显示的基于类的实现更正式,有人会说更合适。但是您可以简单地使用自己的全局变量并编写一个非常短的函数来执行搜索和更新全局变量。谢谢。它按照我想要的方式工作,尽管我希望Python内置了类似的东西。谢谢。这当然有效。但我想知道是否有替代方案,如第二个代码示例所示。显然Python缺少这样的功能。@shipping-Python缺少这个功能,但是自己添加它很简单。这里显示的基于类的实现更正式,有人会说更合适。但是您可以简单地使用自己的全局变量并编写一个非常短的函数来执行搜索和更新全局变量。谢谢。它按照我想要的方式工作,尽管我希望Python内置了类似的东西。