正则表达式前瞻丢弃匹配

Posted

技术标签:

【中文标题】正则表达式前瞻丢弃匹配【英文标题】:Regex lookahead discard a match 【发布时间】:2021-11-15 23:16:54 【问题描述】:

我正在尝试进行正则表达式匹配,它完全放弃了前瞻。

\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*

这是比赛,这是我的regex101 test。

但是,当电子邮件以 -_. 开头时,它不应完全匹配,而不仅仅是删除初始符号。欢迎任何想法,我一直在搜索过去半小时,但不知道如何删除以这些符号开头的整个电子邮件。

【问题讨论】:

【参考方案1】:

您可以使用@ 附近的单词边界和否定的lookbehind 来检查我们是在字符串的开头还是在空格之后,然后检查第一个符号是否不在不需要的类[^\s\-_.] 内:

(?<=^|\s)[^\s\-_.]\w*(?:[-+.]\w+)*\b@\w+(?:[-.]\w+)*\.\w+(?:[-.]\w+)*

见demo

匹配列表:

support@github.com
s.miller@mit.edu
j.hopking@york.ac.uk
steve.parker@soft.de
info@company-hotels.org
kiki@hotmail.co.uk
no-reply@github.com
s.peterson@mail.uu.net
info-bg@software-software.software.academy

关于用法和替代符号的附加说明

请注意,最佳做法是在正则表达式中使用尽可能少的转义字符,因此,[^\s\-_.] 可以写为[^\s_.-],字符类末尾的连字符仍然表示文字连字符,而不是范围。此外,如果您计划在其他正则表达式引擎中使用该模式,您可能会发现在后向交替中遇到困难,然后您可以将 (?&lt;=\s|^) 替换为等效的 (?&lt;!\S)。见this regex:

(?<!\S)[^\s_.-]\w*(?:[-+.]\w+)*\b@\w+(?:[-.]\w+)*\.\w+(?:[-.]\w+)*

最后但同样重要的是,如果您需要在 javascript 或其他不支持环视的语言中使用它,请将 (?&lt;!\S)/(?&lt;=\s|^) 替换为(非)捕获组 (\s|^),包装整个电子邮件模式部分使用另一组捕获括号并使用语言手段来获取第 1 组的内容:

(\s|^)([^\s_.-]\w*(?:[-+.]\w+)*\b@\w+(?:[-.]\w+)*\.\w+(?:[-.]\w+)*)

请参阅regex demo。

【讨论】:

智能使用那里的\b ;)【参考方案2】:

我将它用于多个电子邮件地址,用“;”分隔:

([A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\.[A-Za-z]2,4;)*

对于单个邮件:

[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\.[A-Za-z]2,4

【讨论】:

But when an email starts with - or _ or . it should not match it completely 的解决方案在哪里?

以上是关于正则表达式前瞻丢弃匹配的主要内容,如果未能解决你的问题,请参考以下文章

JS 正则表达式否定匹配(正向前瞻)

匹配带有可选前瞻的正则表达式

Prometheus(公制)使用逆正则表达式匹配/负前瞻重新标记配置

正则表达式忽略分组顺序匹配(前瞻后顾负前瞻负后顾的应用)

正则表达式前瞻(?=)后顾(?<)负前缀(?!)负后顾(?<!)

正则表达式第三回--模式分组与前瞻