Python 前瞻和非捕获正则表达式
我正在尝试将@字符前面的电子邮件地址的本地部分与以下内容匹配:Python 前瞻和非捕获正则表达式,python,regex,regex-lookarounds,Python,Regex,Regex Lookarounds,我正在尝试将@字符前面的电子邮件地址的本地部分与以下内容匹配: LOCAL_RE_NOTQUOTED = """ (( \w # alphanumeric and _ | [!#$%&'*+-/=?^_`{|}~] # special chars, but no dot at beginning ) ( \w # alphanumeric and _ | [!#$%&'*+-/=?^_`{|}~] # speci
LOCAL_RE_NOTQUOTED = """
((
\w # alphanumeric and _
| [!#$%&'*+-/=?^_`{|}~] # special chars, but no dot at beginning
)
(
\w # alphanumeric and _
| [!#$%&'*+-/=?^_`{|}~] # special characters
| ([.](?![.])) # negative lookahead to avoid pairs of dots.
)*)
(?<!\.)(?:@) # no end with dot before @
"""
给出:
'a.a..a@'
为什么输出中会打印@
,即使我使用的是非捕获组(?:@)
使用以下各项进行测试:
re.match(LOCAL_RE_NOTQUOTED, "a.a..a@", re.VERBOSE).group()
re.match(LOCAL_RE_NOTQUOTED, "a.a..a@", re.VERBOSE).groups()
给出:
('a.a..a', 'a', 'a', None)
为什么正则表达式不使用一对点拒绝字符串
“…”
?您混淆了非捕获组(?:…)
和前瞻断言(?=…)
前者确实参与了匹配(因此是包含整体匹配的match.group()
的一部分),它们只是不生成反向引用($1
等供以后使用)
第二个问题(为什么双点匹配?)有点棘手。这是因为正则表达式中有一个错误。你看,当你写的时候(缩短以表达观点)
您编写了“匹配+
和/
之间的字符,在ASCII中,点正好位于它们之间(ASCII 43-47:+,-./
)。因此,第一个字符类匹配点,并且永远不会到达前瞻断言。您需要将破折号放在字符类的末尾,将其视为文字破折号:
((
\w # alphanumeric and _
| [!#$%&'*+/=?^_`{|}~-] # special chars, but no dot at beginning
)
(
\w # alphanumeric and _
| [!#$%&'*+/=?^_`{|}~-] # special characters
| ([.](?![.])) # negative lookahead to avoid pairs of dots.
)*)
(?<!\.)(?=@) # no end with dot before @
有时,更容易使用更简单的正则表达式,如
/([\S]+)@/g
,并在下一步中从不需要的垃圾中过滤输出step@Jakub,是的,但这样做太容易了。:)不过,我想知道为什么它不起作用…
正则表达式中的字符不应该转义吗?(代码的第4行和第8行)@雅库布:不是在角色类里面。非常感谢你的回复。你发现了我正则表达式中的错误,真是难以置信。。。
((
\w # alphanumeric and _
| [!#$%&'*+/=?^_`{|}~-] # special chars, but no dot at beginning
)
(
\w # alphanumeric and _
| [!#$%&'*+/=?^_`{|}~-] # special characters
| ([.](?![.])) # negative lookahead to avoid pairs of dots.
)*)
(?<!\.)(?=@) # no end with dot before @
^(?!\.) # no dot at the beginning
(?:
[\w!#$%&'*+/=?^_`{|}~-] # alnums or special characters except dot
| (\.(?![.@])) # or dot unless it's before a dot or @
)*
(?=@) # end before @