使用正则表达式的结构模式匹配
Structural pattern matching using regex
我有一个字符串,我正在尝试根据一些正则表达式模式验证它,我希望因为模式匹配在 3.10 中可用,所以我可以使用它而不是创建 if-else 块。
考虑一个字符串 'validateString',可能的值为 1021102,1.25.32, string021.
我尝试的代码如下所示。
match validateString:
case regex1:
print('Matched regex1')
case regex2:
print('Matched regex2')
case regex3:
print('Matched regex3')
对于正则表达式 1、2 和 3,我尝试了字符串正则表达式模式以及 re.compile 对象,但它似乎不起作用。
我一直试图在互联网上找到这方面的例子,但似乎找不到任何涵盖正则表达式模式匹配和新 python 模式匹配的例子。
关于如何让它发挥作用的任何想法?
谢谢!
无法使用正则表达式模式通过结构模式匹配进行匹配(此时)。
发件人:PEP0643: structural-pattern-matching
PEP 634: Structural Pattern Matching
Structural pattern matching has been added in the form of a match statement and case statements of patterns with associated actions. Patterns consist of sequences, mappings, primitive data types as well as class instances. Pattern matching enables programs to extract information from complex data types, branch on the structure of data, and apply specific actions based on different forms of data. (emphasis mine)
这里没有任何提示表明在提供的模式上调用 re
模块的匹配/搜索功能旨在用于匹配。
您可以通过阅读实际 PEP 了解更多关于结构模式匹配背后的推理:
- PEP 634 -- Structural Pattern Matching: Specification
- PEP 635 -- Structural Pattern Matching: Motivation and Rationale
- PEP 636 -- Structural Pattern Matching: Tutorial
它们还提供了有关如何使用它的大量示例。
正如 Patrick Artner 在 中正确指出的那样,目前还没有官方方法可以做到这一点。希望该功能将在未来的 Python 版本中引入,并且可以取消此问题。到那时:
PEP 634 指定结构模式匹配使用 ==
运算符来评估匹配。我们可以覆盖它。
import re
from dataclasses import dataclass
# noinspection PyPep8Naming
@dataclass
class regex_in:
string: str
def __eq__(self, other: str | re.Pattern):
if isinstance(other, str):
other = re.compile(other)
assert isinstance(other, re.Pattern)
# TODO extend for search and match variants
return other.fullmatch(self.string) is not None
现在您可以执行以下操作:
match regex_in(validated_string):
case r'\d+':
print('Digits')
case r'\s+':
print('Whitespaces')
case _:
print('Something else')
警告 #1 是您不能将 re.compile
的模式直接传递给案例,因为 Python 想要根据class。您必须先将图案保存在某个地方。
注意事项 #2 您实际上也不能使用局部变量,因为 Python 然后将其解释为捕获匹配主题的名称。您需要使用带点的名称,例如将模式放入 class 或枚举:
class MyPatterns:
DIGITS = re.compile('\d+')
match regex_in(validated_string):
case MyPatterns.DIGITS:
print('This works, it\'s all digits')
群组
这可以进一步扩展,以提供一种访问 re.Match
对象和组的简单方法。
# noinspection PyPep8Naming
@dataclass
class regex_in:
string: str
match: re.Match = None
def __eq__(self, other: str | re.Pattern):
if isinstance(other, str):
other = re.compile(other)
assert isinstance(other, re.Pattern)
# TODO extend for search and match variants
self.match = other.fullmatch(self.string)
return self.match is not None
def __getitem__(self, group):
return self.match[group]
# Note the `as m` in in the case specification
match regex_in(validated_string):
case r'\d(\d)' as m:
print(f'The second digit is {m[1]}')
print(f'The whole match is {m.match}')
我有一个字符串,我正在尝试根据一些正则表达式模式验证它,我希望因为模式匹配在 3.10 中可用,所以我可以使用它而不是创建 if-else 块。
考虑一个字符串 'validateString',可能的值为 1021102,1.25.32, string021.
我尝试的代码如下所示。
match validateString:
case regex1:
print('Matched regex1')
case regex2:
print('Matched regex2')
case regex3:
print('Matched regex3')
对于正则表达式 1、2 和 3,我尝试了字符串正则表达式模式以及 re.compile 对象,但它似乎不起作用。
我一直试图在互联网上找到这方面的例子,但似乎找不到任何涵盖正则表达式模式匹配和新 python 模式匹配的例子。
关于如何让它发挥作用的任何想法?
谢谢!
无法使用正则表达式模式通过结构模式匹配进行匹配(此时)。
发件人:PEP0643: structural-pattern-matching
PEP 634: Structural Pattern Matching
Structural pattern matching has been added in the form of a match statement and case statements of patterns with associated actions. Patterns consist of sequences, mappings, primitive data types as well as class instances. Pattern matching enables programs to extract information from complex data types, branch on the structure of data, and apply specific actions based on different forms of data. (emphasis mine)
这里没有任何提示表明在提供的模式上调用 re
模块的匹配/搜索功能旨在用于匹配。
您可以通过阅读实际 PEP 了解更多关于结构模式匹配背后的推理:
- PEP 634 -- Structural Pattern Matching: Specification
- PEP 635 -- Structural Pattern Matching: Motivation and Rationale
- PEP 636 -- Structural Pattern Matching: Tutorial
它们还提供了有关如何使用它的大量示例。
正如 Patrick Artner 在
PEP 634 指定结构模式匹配使用 ==
运算符来评估匹配。我们可以覆盖它。
import re
from dataclasses import dataclass
# noinspection PyPep8Naming
@dataclass
class regex_in:
string: str
def __eq__(self, other: str | re.Pattern):
if isinstance(other, str):
other = re.compile(other)
assert isinstance(other, re.Pattern)
# TODO extend for search and match variants
return other.fullmatch(self.string) is not None
现在您可以执行以下操作:
match regex_in(validated_string):
case r'\d+':
print('Digits')
case r'\s+':
print('Whitespaces')
case _:
print('Something else')
警告 #1 是您不能将 re.compile
的模式直接传递给案例,因为 Python 想要根据class。您必须先将图案保存在某个地方。
注意事项 #2 您实际上也不能使用局部变量,因为 Python 然后将其解释为捕获匹配主题的名称。您需要使用带点的名称,例如将模式放入 class 或枚举:
class MyPatterns:
DIGITS = re.compile('\d+')
match regex_in(validated_string):
case MyPatterns.DIGITS:
print('This works, it\'s all digits')
群组
这可以进一步扩展,以提供一种访问 re.Match
对象和组的简单方法。
# noinspection PyPep8Naming
@dataclass
class regex_in:
string: str
match: re.Match = None
def __eq__(self, other: str | re.Pattern):
if isinstance(other, str):
other = re.compile(other)
assert isinstance(other, re.Pattern)
# TODO extend for search and match variants
self.match = other.fullmatch(self.string)
return self.match is not None
def __getitem__(self, group):
return self.match[group]
# Note the `as m` in in the case specification
match regex_in(validated_string):
case r'\d(\d)' as m:
print(f'The second digit is {m[1]}')
print(f'The whole match is {m.match}')