在Python中,如何将正则表达式子模式与命名组一起使用?

在Python中,如何将正则表达式子模式与命名组一起使用?,python,regex,perl,Python,Regex,Perl,我正在将一个需要大量正则表达式的脚本从Perl翻译成Python,我对正则表达式子模式有一个问题 在Perl中,如果我按照预期编写以下工作,即编写字符串“OK”。我从来没有仔细考虑过,但看起来Perl知道这些是不同的组,尽管它们有相同的名称 my $ident = qr{ (?<guill> ['"`]? ) [a-zA-Z_] \w* \g{guill} }x; my $idents = qr{ (?: $ident \s* , \s* )* $ident }x; my $tes

我正在将一个需要大量正则表达式的脚本从Perl翻译成Python,我对正则表达式子模式有一个问题

在Perl中,如果我按照预期编写以下工作,即编写字符串“OK”。我从来没有仔细考虑过,但看起来Perl知道这些是不同的组,尽管它们有相同的名称

my $ident  = qr{ (?<guill> ['"`]? ) [a-zA-Z_] \w* \g{guill} }x;
my $idents = qr{ (?: $ident \s* , \s* )* $ident }x;
my $test   =  q{'test', "test"};

if ($test =~ $idents) {
    say 'OK';
}
my$ident=qr{(?['“`])[a-zA-Z!]\w*\g{guill}x;
my$ident=qr{(?$ident\s*,\s*)*$ident}x;
my$test=q{'test','test};
如果($test=~$idents){
说‘好’;
}
在Python中,除了在将字符串编译为正则表达式模式之前对其进行相关处理外,我没有找到在模式中插入子模式的方法,因此我将Perl代码翻译为:

ident  = r"(?P<guill> ['\"`]? ) [a-zA-Z_] \w* (P=guill)"
idents = r"(?: " + ident + r" \s* , \s* )* " + ident
test   = "'test', \"test\""

if re.match( idents, test, re.VERBOSE ):
    print "OK"
ident=r“(?P['\''`]?)[a-zA-Z\]\w*(P=guill)”
idents=r“(?:“+ident+r”\s*,\s*)*“+ident
test=“'test',\“test\”
如果重新匹配(标识、测试、详细):
打印“确定”
毫不奇怪,这甚至没有编译,因为Python抱怨“将组名'guill'重新定义为组3”。我尝试了Perlish方法并重新编译了
ident
,但它拒绝将字符串与模式对象连接起来


Pythonish实现这一点的方法是什么?

这可以使用真正的正则表达式来实现

ident0 = r"[a-zA-Z_] \w*"
ident1 = r"' [a-zA-Z_] \w* '"
ident2 = r"\" [a-zA-Z_] \w* \""
ident3 = r"` [a-zA-Z_] \w* `"
ident  = "(?:" + ident0 + "|" + ident1 + "|" + ident2 + "|" + ident3 + ")"

与@ikegami的答案几乎相同,但没有
ident
名称(通常表明列表是更好的选择),也没有更具Pythonic风格的
“|”。join

subidents = [
    r"[a-zA-Z_] \w*",
    r"'[a-zA-Z_] \w* '",
    r"\"[a-zA-Z_] \w* \"",
    r"`[a-zA-Z_] \w* `",
    ]
ident = "(?:%s)" % '|'.join(subidents)
现在,您可以扩展子标识列表,以获得更多的子标识


专业提示:如果您以后可能会添加更多项,请在最后一个列表项后添加一个逗号-在比较版本时减少无关的更改行。

Python正则表达式只有反向引用,但不能使用子模式。AFIK您不能定义两次相同的命名组。但是您可以安装模块“regex”而不是“re”,它有更多的功能。谢谢,我只是按照您的建议。新的包有一些有趣的特性,但不幸的是子模式似乎不在其中。@Casimir et Hippolyte,上面发布的Perl代码没有使用任何子模式,只是命名为捕获
qr{(?:(?^x:(?[''''''`]?)[a-zA-Z]\w*\g{guill}]s*,\s*)*(?^x:(?[''''''''''`]?)[a-zA-Z]\w*\g{guill})x
将是等效的。Re“我在Python中除了包含字符串外,没有办法在模式内插入子模式”,这也是您的Perl代码所做的。谢谢。我希望一种比Perl更优雅的语言能够有一个更干净的解决方案。。。