Python正则表达式的匹配顺序错误,并替换组内的匹配项
示例字符串:Python正则表达式的匹配顺序错误,并替换组内的匹配项,python,regex,Python,Regex,示例字符串: base_A23x4_B534x5_C654x6_D2363x45 所需匹配项: basename=base A=23.4 B=534.5 C=654.6 D=2363.45 这是到目前为止我的正则表达式: (?P<basename>\w+)_A(?P<A>[0-9]+x[0-9]+)_B(?P<B>[0-9]+x[0-9]+)_C(?P<C>[0-9]+x[0-9]+)_D(?P<D>[0-9]+x[0-9]+)
base_A23x4_B534x5_C654x6_D2363x45
所需匹配项:
basename=base
A=23.4
B=534.5
C=654.6
D=2363.45
这是到目前为止我的正则表达式:
(?P<basename>\w+)_A(?P<A>[0-9]+x[0-9]+)_B(?P<B>[0-9]+x[0-9]+)_C(?P<C>[0-9]+x[0-9]+)_D(?P<D>[0-9]+x[0-9]+)
(?P\w+)\u A(?P[0-9]+x[0-9]+)\u B(?P[0-9]+x[0-9]+)\u C(?P[0-9]+x[0-9]+)\u D(?P[0-9]+x[0-9]+)
我有两个问题:
使用lookaheads中的捕获组以任意顺序获取它们。还请注意,您应该使用
\d
而不是[0-9]
,并且如果您想要单独命名的捕获组(例如用于\u A
部分,而用于\u B
部分),则应该使用单独的捕获组名称,而不是重复
:
输出:
['_D2363x45', '_B534x5', '_C654x6', '_A23x4']
使用lookaheads中的捕获组以任意顺序获取它们。还请注意,您应该使用\d
而不是[0-9]
,并且如果您想要单独命名的捕获组(例如用于\u A
部分,而用于\u B
部分),则应该使用单独的捕获组名称,而不是重复
:
输出:
['_D2363x45', '_B534x5', '_C654x6', '_A23x4']
您可以使用前瞻模式:
import re
s = 'base_A23x4_B534x5_C654x6_D2363x45'
basename, *numbers = re.match(r'([^_]+)(?=.*(?<=_)A(\d+x\d+))(?=.*(?<=_)B(\d+x\d+))(?=.*(?<=_)C(\d+x\d+))(?=.*(?<=_)D(\d+x\d+))', s).groups()
A, B, C, D = [n.replace('x', '.') for n in numbers]
将A
的值移动到字符串的末尾:
s = 'base_B534x5_C654x6_D2363x45_A23x4'
结果将保持不变
编辑:鉴于您的新要求,即字符串中可能有任意数量的字母组合,您应该将字符串拆分为标记,以将其转换为dict:
import re
s = 'base_A23x4_B534x5_C654x6_D2363x45_AA12x3'
basename, *tokens = s.split('_')
print({k: v.replace('x', '.') for k, v in dict(re.match(r'([A-Z]+)([\dx]+)', n).groups() for n in tokens).items()})
这将产生:
{'A': '23.4', 'B': '534.5', 'C': '654.6', 'D': '2363.45', 'AA': '12.3'}
您可以使用前瞻模式:
import re
s = 'base_A23x4_B534x5_C654x6_D2363x45'
basename, *numbers = re.match(r'([^_]+)(?=.*(?<=_)A(\d+x\d+))(?=.*(?<=_)B(\d+x\d+))(?=.*(?<=_)C(\d+x\d+))(?=.*(?<=_)D(\d+x\d+))', s).groups()
A, B, C, D = [n.replace('x', '.') for n in numbers]
将A
的值移动到字符串的末尾:
s = 'base_B534x5_C654x6_D2363x45_A23x4'
结果将保持不变
编辑:鉴于您的新要求,即字符串中可能有任意数量的字母组合,您应该将字符串拆分为标记,以将其转换为dict:
import re
s = 'base_A23x4_B534x5_C654x6_D2363x45_AA12x3'
basename, *tokens = s.split('_')
print({k: v.replace('x', '.') for k, v in dict(re.match(r'([A-Z]+)([\dx]+)', n).groups() for n in tokens).items()})
这将产生:
{'A': '23.4', 'B': '534.5', 'C': '654.6', 'D': '2363.45', 'AA': '12.3'}
我在原始邮件中出错了。我的意思是每个组都有单独的命名捕获组。是否有基于匹配自动生成名称的方法?我不限于4组(A、B、C、D)。我可以有50个用大写字母命名的组。这样自动生成命名的捕获组是不可能的,不过通过regex
模块,您可以得到重复的捕获组,以后可以解析。(或者您可以在找到的basename
和相关子字符串上使用findall
,但不确定这是否是您的选项)我在原始帖子中出错。我的意思是每个组都有单独的命名捕获组。是否有基于匹配自动生成名称的方法?我不限于4组(A、B、C、D)。我可以有50个用大写字母命名的组。这样自动生成命名的捕获组是不可能的,不过通过regex
模块,您可以得到重复的捕获组,以后可以解析。(或者您可以在找到的basename
和相关子字符串上使用findall
,但不确定这是否是您的选项)我是。请仔细查看。因为x
也可以出现在basename中,所以您不想在s
中用替换x
。你只需要对每个标记的值进行操作。我是。请仔细查看。因为x
也可以出现在basename中,所以您不想在s
中用替换x
。您必须只针对每个令牌的值进行更新。以后请不要使用与原始问题明显不同的要求更新您的问题。回答您的原始问题会浪费我们的时间,而这些问题根本不适用于您的更新问题。今后,请不要使用与原始问题显著不同的要求更新您的问题。我们浪费时间回答你原来的问题,而这些问题根本不适用于你更新的问题。