python - 前瞻和非捕获正则表达式

标签 python regex regex-lookarounds

我正在尝试将 @ 字符之前的电子邮件地址的本地部分与:

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 @
"""

测试:

re.match(LOCAL_RE_NOTQUOTED, "a.a..a@", re.VERBOSE).group()

给出:

'a.a..a@'

为什么 @ 打印在输出中,即使我使用的是非捕获组 (?:@)

测试:

 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 @

当然,如果你想使用这个逻辑,你可以稍微简化一下:

^(?!\.)                   # no dot at the beginning
(?:
[\w!#$%&'*+/=?^_`{|}~-]   # alnums or special characters except dot
| (\.(?![.@]))            # or dot unless it's before a dot or @ 
)*
(?=@)                     # end before @

关于python - 前瞻和非捕获正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7040829/

相关文章:

java - 用于在字符串中查找模式的正则表达式

python - 带有附加参数的自定义 django 管理命令

JAVA正则表达式失败

python - 函数定义上的正则表达式 findall。想要匹配参数但不匹配函数

java - 最小和最大字符数正则表达式

python - 如何在 SPARQL regex() 中使用逻辑或?

正则表达式排除查找工具的单词

python - 我从 Python 中的地理编码器中提取的一些坐标没有保存在我创建的变量中

python - 无法使用 Python3 格式化来自 Linux 的输出数据

python - 为什么Python看不到环境变量?