Python 如何在正则表达式中为一组条件定义量词?
我有这个字符串:Python 如何在正则表达式中为一组条件定义量词?,python,regex,Python,Regex,我有这个字符串: "Za @Foo_Bar: @BAR_foo @FooBAR @BArfoo" 还有这样的正则表达式模式: ((Za\s)?@[A-Za-z0-9_]*)|(@[A-Za-z0-9_]*) 或 我希望它返回以下列表: ['Za @Foo_Bar','BAR_foo','FooBAR','BArfoo'] 但我得到了意想不到的结果: >>> import re >>> import regex >>> a = "Za
"Za @Foo_Bar: @BAR_foo @FooBAR @BArfoo"
还有这样的正则表达式模式:
((Za\s)?@[A-Za-z0-9_]*)|(@[A-Za-z0-9_]*)
或
我希望它返回以下列表:
['Za @Foo_Bar','BAR_foo','FooBAR','BArfoo']
但我得到了意想不到的结果:
>>> import re
>>> import regex
>>> a = "Za @Foo_Bar: @BAR_foo @FooBAR @BArfoo"
>>> regex.fullmatch(u'((Za\s)?@[A-Za-z0-9_]*)|(@[A-Za-z0-9_]*)',a) is None
True
>>> re.findall(u'((Za\s)?@[A-Za-z0-9_]*)|(@[A-Za-z0-9_]*)',a)
[('Za @Foo_Bar', 'Za ', ''), ('@BAR_foo', '', ''), ('@FooBAR', '', ''), ('@BArfoo', '', '')]
第二个结果更具说服力,但它包含许多垃圾值:
>>> regex.findall(u'((Za\s)?@[A-Za-z0-9_]*)|(@[A-Za-z0-9_]*)',a)
[('Za @Foo_Bar', 'Za ', ''), ('@BAR_foo', '', ''), ('@FooBAR', '', ''), ('@BArfoo', '', '')]
>>> match = re.search(u'((Za\s)?@[A-Za-z0-9_]*)|(@[A-Za-z0-9_]*)',a)
>>> match.groups()
('Za @Foo_Bar', 'Za ', None)
为什么
fullmatch
返回None
?如何获得一个干净的列表?作为替代方法,您可以使用(?并在可选冒号上拆分,后跟空格和@
,字符串中的第一个除外:
import re
s = "Za @Foo_Bar: @BAR_foo @FooBAR @BArfoo"
print(re.split('(?<!\AZa):? @', s))
|作为替代,您可以使用(?并在可选冒号上拆分,后跟空格和@
,字符串中的第一个除外:
import re
s = "Za @Foo_Bar: @BAR_foo @FooBAR @BArfoo"
print(re.split('(?<!\AZa):? @', s))
|regex.fullmatch()
是这里使用的错误方法,我认为您不理解它的用途
从:
fullmatch
的行为类似于match
,只是它必须匹配所有字符串
您的模式不匹配所有输入字符串。只有当模式覆盖了从第一个字符到最后一个字符的所有内容时,fullmatch()
才会返回匹配
其中,re.match()
仅在字符串开头匹配,就像您将\A
添加到模式的开头一样,regex.fullmatch()
匹配,就像您将\A
添加到模式的开头,并且将\Z
添加到模式的结尾一样
请注意,您不需要|(@[A-Za-z0-9\]*)
选项;当(Za\s)?@[A-Za-z0-9\]*
部分与(Za\s)?
不匹配时,该模式已完全覆盖
要获得一个干净的列表,请使用re.findall()
,但要使用(?:…)
非捕获组来覆盖可选部分,这样就不会在re.findall()
结果中获得单独的字符串:
>>> import re
>>> a = "Za @Foo_Bar: @BAR_foo @FooBAR @BArfoo"
>>> re.findall(r'(?:Za\s)?@[A-Za-z0-9_]*', a)
['Za @Foo_Bar', '@BAR_foo', '@FooBAR', '@BArfoo']
在没有捕获组的情况下,将返回整个匹配。regex.fullmatch()
在这里使用的方法是错误的,我认为您不了解它的用途
从:
fullmatch
的行为类似于match
,只是它必须匹配所有字符串
您的模式不匹配所有输入字符串。只有当模式覆盖了从第一个字符到最后一个字符的所有内容时,fullmatch()
才会返回匹配
其中,re.match()
仅在字符串开头匹配,就像您将\A
添加到模式的开头一样,regex.fullmatch()
匹配,就像您将\A
添加到模式的开头,并且将\Z
添加到模式的结尾一样
请注意,您不需要|(@[A-Za-z0-9\]*)
选项;当(Za\s)?@[A-Za-z0-9\]*
部分与(Za\s)?
不匹配时,该模式已完全覆盖
要获得一个干净的列表,请使用re.findall()
,但要使用(?:…)
非捕获组来覆盖可选部分,这样就不会在re.findall()
结果中获得单独的字符串:
>>> import re
>>> a = "Za @Foo_Bar: @BAR_foo @FooBAR @BArfoo"
>>> re.findall(r'(?:Za\s)?@[A-Za-z0-9_]*', a)
['Za @Foo_Bar', '@BAR_foo', '@FooBAR', '@BArfoo']
如果没有捕获组,则返回整个匹配。不使用组:
import re
s = "Za @Foo_Bar: @BAR_foo @FooBAR @BArfoo"
g = re.findall(r'(?:Za\s)@\w+|(?<=@)\w+', s)
print(g)
说明:
['Za @Foo_Bar', 'BAR_foo', 'FooBAR', 'BArfoo']
(?:Za\s) # non capture group
@ # @
\w+ # 1 or more word character
| #
(?<=@) # lookbehind, make sure we have @ before
\w+ # 1 or more word character
(?:Za\s)#非捕获组
@ # @
\w+#1个或多个单词字符
| #
(?不要使用组:
import re
s = "Za @Foo_Bar: @BAR_foo @FooBAR @BArfoo"
g = re.findall(r'(?:Za\s)@\w+|(?<=@)\w+', s)
print(g)
说明:
['Za @Foo_Bar', 'BAR_foo', 'FooBAR', 'BArfoo']
(?:Za\s) # non capture group
@ # @
\w+ # 1 or more word character
| #
(?<=@) # lookbehind, make sure we have @ before
\w+ # 1 or more word character
(?:Za\s)#非捕获组
@ # @
\w+#1个或多个单词字符
| #
(?