Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.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_Lookahead_Lookbehind_Lookaround - Fatal编程技术网

Python正则表达式在连字符后查找非数字范围的匹配组,如果范围不存在,则忽略模式的其余部分

Python正则表达式在连字符后查找非数字范围的匹配组,如果范围不存在,则忽略模式的其余部分,python,regex,lookahead,lookbehind,lookaround,Python,Regex,Lookahead,Lookbehind,Lookaround,我对更高级的正则表达式概念比较新,并开始研究look behinds和lookaheads,但我感到困惑,需要一些指导。我有一个场景,在这个场景中,我可能会有几种不同类型的发布拉链,它们的名称如下: v1.1.2-beta.2.zip v1.1.2.zip 我想写一个单行正则表达式,它可以找到两种类型的匹配组。例如,如果文件类型是第一个zip,我需要三个匹配组,如下所示: v1.1.2-beta.2.zip Group 1: v1.1.2 Group 2: beta Group 3. 2 或

我对更高级的正则表达式概念比较新,并开始研究look behinds和lookaheads,但我感到困惑,需要一些指导。我有一个场景,在这个场景中,我可能会有几种不同类型的发布拉链,它们的名称如下:

v1.1.2-beta.2.zip
v1.1.2.zip
我想写一个单行正则表达式,它可以找到两种类型的匹配组。例如,如果文件类型是第一个zip,我需要三个匹配组,如下所示:

v1.1.2-beta.2.zip
Group 1: v1.1.2
Group 2: beta
Group 3. 2
或者,如果第二个zip为一个匹配组:

v1.1.2.zip
Group 1: v1.1.2
这就是我开始感到困惑的地方,因为我假设正则表达式需要断言连字符是否存在,如果不存在,则只查找一个匹配组,如果不存在,则查找其他3个

(v[0-9.]{0,}).([A-Za-z]{0,}).([0-9]).zip
这是我编写的初始正则表达式,它成功地匹配了第一种类型,但没有条件。我曾考虑在连字符后匹配非数字的组范围,但无法让它正常工作,也不知道如何让它忽略模式的其余部分,如果找不到连字符,就只接受第一个组

([\D]{0,}(?=[-]) # Does not work

有人能给我指出正确的方向吗?

我们可以使用以下正则表达式:

(v\d+(?:\.\d+)*)(?:[-]([A-Za-z]+))?((?:\.\d+)*)\.zip
这样就产生了三组:第一组是版本,第二组是可选的:破折号,后跟字母字符,然后是可选的点序列,后跟数字,最后是.zip

如果我们忽略\.zip后缀,那么我认为这相当简单,那么仍然有三个组:

v\d+?:\。\d+*:以v开头,后跟\d+一个或多个数字的正则表达式组。然后我们有一个非捕获组a组以?:。。它捕获\.\d+一个点,后跟一个或多个数字序列。我们将这样的子组重复零次或多次

?:[-][A-Za-z]+?:以连字符[-]开头,然后是一个或多个[A-Za-z]字符的捕获组。但是,捕获组是可选的?最后

?:\。\d+*:一个组又有这样的\.\d+非捕获子组,所以我们捕获一个点,后跟一个数字序列,这个模式重复零次或多次

例如:

rgx = re.compile(r'(v\d+(?:\.\d+)*)([-][A-Za-z]+)?((?:\.\d+)*)\.zip')
然后我们获得:

>>> rgx.findall('v1.1.2-beta.2.zip')
[('v1.1.2', '-beta', '.2')]
>>> rgx.findall('v1.1.2.zip')
[('v1.1.2', '', '')]

我们可以使用以下正则表达式:

(v\d+(?:\.\d+)*)(?:[-]([A-Za-z]+))?((?:\.\d+)*)\.zip
这样就产生了三组:第一组是版本,第二组是可选的:破折号,后跟字母字符,然后是可选的点序列,后跟数字,最后是.zip

如果我们忽略\.zip后缀,那么我认为这相当简单,那么仍然有三个组:

v\d+?:\。\d+*:以v开头,后跟\d+一个或多个数字的正则表达式组。然后我们有一个非捕获组a组以?:。。它捕获\.\d+一个点,后跟一个或多个数字序列。我们将这样的子组重复零次或多次

?:[-][A-Za-z]+?:以连字符[-]开头,然后是一个或多个[A-Za-z]字符的捕获组。但是,捕获组是可选的?最后

?:\。\d+*:一个组又有这样的\.\d+非捕获子组,所以我们捕获一个点,后跟一个数字序列,这个模式重复零次或多次

例如:

rgx = re.compile(r'(v\d+(?:\.\d+)*)([-][A-Za-z]+)?((?:\.\d+)*)\.zip')
然后我们获得:

>>> rgx.findall('v1.1.2-beta.2.zip')
[('v1.1.2', '-beta', '.2')]
>>> rgx.findall('v1.1.2.zip')
[('v1.1.2', '', '')]
您可以使用re.findall:

请注意,从re.findall获得的结果是:

您可以使用re.findall:

请注意,从re.findall获得的结果是:


下面是我将如何使用re.search来实现这一点。请注意,我们不需要在这里寻找周围环境;只要一个相当复杂的模式就行了

import re

regex = r"(v\d+(?:\.\d+)*)(?:-(\w+)\.(\d+))?\.zip"

str1 = "v1.1.2-beta.2.zip"
str2 = "v1.1.2.zip"
match = re.search(regex, str1)

print(match.group(1))
print(match.group(2))
print(match.group(3))

print("\n")
match = re.search(regex, str2)

print(match.group(1))

v1.1.2
beta
2

v1.1.2

如果您对regex没有太多的经验,那么提供每个步骤的解释可能不会让您跟上进度。不过,我将对一些括号中出现的?:的用法进行评论。在这种情况下,?:告诉正则表达式引擎不要捕获内部内容。我们这样做是因为您最多只想捕获三件特定的事情。

以下是我将如何使用re.search来实现这一点。请注意,我们不需要在这里寻找周围环境;只要一个相当复杂的模式就行了

import re

regex = r"(v\d+(?:\.\d+)*)(?:-(\w+)\.(\d+))?\.zip"

str1 = "v1.1.2-beta.2.zip"
str2 = "v1.1.2.zip"
match = re.search(regex, str1)

print(match.group(1))
print(match.group(2))
print(match.group(3))

print("\n")
match = re.search(regex, str2)

print(match.group(1))

v1.1.2
beta
2

v1.1.2

如果您对regex没有太多的经验,那么提供每个步骤的解释可能不会让您跟上进度。不过,我将对一些括号中出现的?:的用法进行评论。在这种情况下,?:告诉正则表达式引擎不要捕获内部内容。我们这样做是因为您最多只想捕获三个特定的内容。

您介意为我更详细地解释一下这个正则表达式吗?我只是想了解properly@ReaganKirby:是的,一分钟。这里唯一的问题是我们想从第一个匹配中排除连字符group@ReaganKirby:没有连字符是第一个模式的一部分,已更新。我的意思是,如果连字符存在,我希望匹配beta而不是-beta。除此之外,这是完美的,有意义的你介意给我解释一下这个正则表达式的细节吗?我只是想了解properly@ReaganK
艾比:是的,一分钟。这里唯一的问题是我们想在第一次比赛中排除连字符group@ReaganKirby:没有连字符是第一个模式的一部分,已更新。我的意思是,如果连字符存在,我希望匹配beta而不是-beta。除此之外,这是完美和有意义的