Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python正则表达式中的上一组匹配_Python_Regex - Fatal编程技术网

Python正则表达式中的上一组匹配

Python正则表达式中的上一组匹配,python,regex,Python,Regex,我试图捕获字符串的片段,这些片段看起来像%a,%b,等等,并用一些值替换它们。此外,我希望能够通过键入%%来转义%%字符 在示例字符串%d%%f%x%%%g中,我希望匹配%d%%f%x%%%g(%d,%x,%g) 我的正则表达式如下所示: (?:[^%]|^)(?:%%)*(%[a-z]) (?:[^%]|^)-匹配行首或与% (?:%%)*-匹配0次或多次出现的%%(转义的%) ([a-z])-与%a、%b等模式的正确匹配 添加前两个元素以支持转义%字符 但是,在示例字符串上运行rege

我试图捕获字符串的片段,这些片段看起来像
%a
%b
,等等,并用一些值替换它们。此外,我希望能够通过键入
%%
来转义
%%
字符

在示例字符串
%d%%f%x%%%g
中,我希望匹配
%d%%f%x%%%g
%d
%x
%g

我的正则表达式如下所示:

(?:[^%]|^)(?:%%)*(%[a-z])
  • (?:[^%]|^)
    -匹配行首或与
    %
  • (?:%%)*
    -匹配0次或多次出现的
    %%
    (转义的
    %
  • ([a-z])
    -与
    %a
    %b
    等模式的正确匹配
添加前两个元素以支持转义
%
字符

但是,在示例字符串上运行regexp时,找不到最后一个片段(
%g
):

>>> import re
>>> pat = re.compile("(?:[^%]|^)(?:%%)*(%[a-z])")
>>> pat.findall("%d%%f%x%%%g")
['%d', '%x']
但是在
%%%g
之前添加一个字符后,它开始正常工作:

>>> pat.findall("%d%%f%x %%%g")
['%d', '%x', '%g']

在匹配到组
([a-z])
后,
x
似乎不再匹配到
[^%]
。如何更改regexp以强制它再次检查上一个匹配的最后一个字符?我读到了
\G
,但它没有帮助。

为什么它没有选择
%G

要选择
%g
,它必须在前面有
%%
。甚至在此之前,它必须有一个
非%
字符,或者在字符串的开头。因此,
x%%%g
可以为您找到匹配项。但此
x
是在上次匹配时(即打印
%x
时)拾取的

简单地说,在正则表达式匹配上有重叠。所以你可以用下面的方法来克服这个问题。我正在将正则表达式放入
(?=…)


您需要以稍微不同的方式构造正则表达式:

>>> import re
>>> regex = re.compile(r"(?:[^%]|%%)*(%[a-z])")
>>> regex.findall("%d%%f%x%%%g")
['%d', '%x', '%g']
说明:


在我看来,您只想捕获前面有偶数个
%
的每个部分
%x


如果是,则模式为
“(?很好的解释,尽管正则表达式不需要那么复杂。很好的解释,尽管正则表达式不需要那么复杂。很好的解释,尽管正则表达式不需要那么复杂。您的解决方案将匹配
%%f
,这是不正确的,因为
%%
应解释为转义
%%
>.简单的模式,尽管没有解释。:@TimPietzcker谢谢:)这正是我想要实现的!
>>> import re
>>> regex = re.compile(r"(?:[^%]|%%)*(%[a-z])")
>>> regex.findall("%d%%f%x%%%g")
['%d', '%x', '%g']
(?:      # Start of a non-capturing group:
 [^%]    # Either match any character except %
|        # or
 %%      # match an "escaped" %.
)*       # Do this any number of times.
(        # Match and capture in group 1:
 %[a-z]  # % followed by a lowercase ASCII alphanumeric
)        # End of capturing group