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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.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,我有下面的正则表达式,它应该可以拉出3个组 ^(ser-num.*|\[ser-num.*])(?: )?(\w+)?(?: )?(http://.*\.com/(?:s(?:erial)?|p(?:roduct)?)/\d+(?:/)?(?:\d+|(?:\w|-)+)?) 这两个字符串: strings = [ "ser-num recommend http://example.com/s/123456 ", "ser-num http://example.com/s/12

我有下面的正则表达式,它应该可以拉出3个组

^(ser-num.*|\[ser-num.*])(?: )?(\w+)?(?: )?(http://.*\.com/(?:s(?:erial)?|p(?:roduct)?)/\d+(?:/)?(?:\d+|(?:\w|-)+)?)
这两个字符串:

strings = [
    "ser-num recommend http://example.com/s/123456 ",
    "ser-num http://example.com/s/123456 ",
]
当我对正则表达式运行这些时,我收到以下组:

('ser-num recommend ', None, 'http://example.com/s/123456')
('ser-num ', None, 'http://example.com/s/123456')
为什么我的第一个结果是将“推荐”组合到组
\1
,而不是
\2

这是我的整个示例脚本:

import re

p = re.compile("""^(ser-num.*|\[ser-num.*])(?: )?(\w+)?(?: )?(http://.*\.com/(?:s(?:erial)?|p(?:roduct)?)/\d+(?:/)?(?:\d+|(?:\w|-)+)?)""")

strings = [
    "ser-num recommend http://example.com/s/123456 ",
    "ser-num http://example.com/s/123456 ",
]

for s in strings:
    m = p.match(s)
    try:
        print m.groups()
    except AttributeError:
        print "Not a match for %s" % (s)
我的正则表达式的值表示可选组
\2
确实存在

根据评论更新:

如果我使用这个正则表达式

^(ser-num.*|\[ser-num.*])\s?(\w*)\s?(http://.*\.com/(?:s(?:erial)?|p(?:roduct)?)/\d+(?:/)?(?:\d+|(?:\w|-)+)?)
我收到这些结果(注意组
\2
中的空字符串而不是
None


我建议使用以下regexp:

^(\[?ser-num\S*]?)\s*(\w*)\s*(http://.*\.com/(?:s(?:erial)?|p(?:roduct)?)/\d+(?:/)?(?:\d+|(?:\w|-)+)?)

这(特别是取代
*
\S*
)强制
(\w*)
位于其自己的捕获组中,而不是被第一个
ser-num.*
字符组吞噬。请注意,第一组中的额外空格也是出于同样的原因,也就是说,它们被贪婪地捕获,而不是作为可选的匹配被丢弃。

我建议使用以下regexp:

^(\[?ser-num\S*]?)\s*(\w*)\s*(http://.*\.com/(?:s(?:erial)?|p(?:roduct)?)/\d+(?:/)?(?:\d+|(?:\w|-)+)?)

这(特别是取代
*
\S*
)强制
(\w*)
位于其自己的捕获组中,而不是被第一个
ser-num.*
字符组吞噬。请注意,第一组中的额外空格也是出于同样的原因,也就是说,它们被贪婪地捕获,而不是作为可选的匹配被丢弃。

我建议使用以下regexp:

^(\[?ser-num\S*]?)\s*(\w*)\s*(http://.*\.com/(?:s(?:erial)?|p(?:roduct)?)/\d+(?:/)?(?:\d+|(?:\w|-)+)?)

这(特别是取代
*
\S*
)强制
(\w*)
位于其自己的捕获组中,而不是被第一个
ser-num.*
字符组吞噬。请注意,第一组中的额外空格也是出于同样的原因,也就是说,它们被贪婪地捕获,而不是作为可选的匹配被丢弃。

我建议使用以下regexp:

^(\[?ser-num\S*]?)\s*(\w*)\s*(http://.*\.com/(?:s(?:erial)?|p(?:roduct)?)/\d+(?:/)?(?:\d+|(?:\w|-)+)?)

这(特别是取代
*
\S*
)强制
(\w*)
位于其自己的捕获组中,而不是被第一个
ser-num.*
字符组吞噬。请注意,由于同样的原因,您在第一个组中获得了额外的空格,即它们被贪婪地捕获,而不是作为可选的匹配被丢弃。

单词
推荐
是第一个组的一部分,因为它匹配部分regexp
ser-num.
。星形运算符返回可能最长的匹配。如果想要最短的匹配,请使用
*?

试试这个:

p = re.compile("""^(ser-num.*?|\[ser-num.*?])(?: )?(\w+)?(?: )?(http://.*\.com/(?:s(?:erial)?|p(?:roduct)?)/\d+(?:/)?(?:\d+|(?:\w|-)+)?)""")
注意使用非贪婪星型:
ser-num.*?

参考:

  • 此处的
    *?
    +?
    ??
    条目:

单词
推荐
属于第一组,因为它与部分regexp
ser-num.*
匹配。星形运算符返回可能最长的匹配。如果想要最短的匹配,请使用
*?

试试这个:

p = re.compile("""^(ser-num.*?|\[ser-num.*?])(?: )?(\w+)?(?: )?(http://.*\.com/(?:s(?:erial)?|p(?:roduct)?)/\d+(?:/)?(?:\d+|(?:\w|-)+)?)""")
注意使用非贪婪星型:
ser-num.*?

参考:

  • 此处的
    *?
    +?
    ??
    条目:

单词
推荐
属于第一组,因为它与部分regexp
ser-num.*
匹配。星形运算符返回可能最长的匹配。如果想要最短的匹配,请使用
*?

试试这个:

p = re.compile("""^(ser-num.*?|\[ser-num.*?])(?: )?(\w+)?(?: )?(http://.*\.com/(?:s(?:erial)?|p(?:roduct)?)/\d+(?:/)?(?:\d+|(?:\w|-)+)?)""")
注意使用非贪婪星型:
ser-num.*?

参考:

  • 此处的
    *?
    +?
    ??
    条目:

单词
推荐
属于第一组,因为它与部分regexp
ser-num.*
匹配。星形运算符返回可能最长的匹配。如果想要最短的匹配,请使用
*?

试试这个:

p = re.compile("""^(ser-num.*?|\[ser-num.*?])(?: )?(\w+)?(?: )?(http://.*\.com/(?:s(?:erial)?|p(?:roduct)?)/\d+(?:/)?(?:\d+|(?:\w|-)+)?)""")
注意使用非贪婪星型:
ser-num.*?

参考:

  • 此处的
    *?
    +?
    ??
    条目:

为什么你用
(?:)?
来表示空格,而不是仅仅用`?`?或者甚至可能用
\s*
来表示空格,用
(\w*)
来表示可选单词?罪魁祸首是
*
;使用
\S*
进行贪婪的非空格字符匹配。为什么要使用
(?:)?
进行空格匹配,而不仅仅是使用`?`?或者甚至可能使用
\S*
进行空格匹配,
(\w*)
进行可选单词匹配?罪魁祸首是
*
;使用
\S*
进行贪婪的非空格字符匹配。为什么要使用
(?:)?
进行空格匹配,而不仅仅是使用`?`?或者甚至可能使用
\S*
进行空格匹配,
(\w*)
进行可选单词匹配?罪魁祸首是
*
;使用
\S*
进行贪婪的非空格字符匹配。为什么要使用
(?:)?
进行空格匹配,而不仅仅是使用`?`?或者甚至可能使用
\S*
进行空格匹配,
(\w*)
进行可选单词匹配?罪魁祸首是
*
;使用
\S*
进行贪婪的非空格字符匹配。明显的“应用非贪婪匹配”提供了最简单的更改+1显而易见的“应用非贪婪匹配”提供了最简单的更改+1显而易见的“应用非贪婪匹配”提供了最简单的更改+1显而易见的“应用非贪婪匹配”提供了最简单的更改+1.