关于一条正则匹配规则的若干条方案讨论

最近遇到一个需求需要使用正则表达式实现,内容如下:

1、可以包含字母、数字、下划线、破折号、点
2、不能以点开头或结尾

方案1(错解)

^[^.][A-Za-z0-9-_.]*[^.]$

(菜鸡本人提供)

发现此方案不能匹配单个英文字符,原因为前面的 [^.] 和 后面的 [^.] 都表示必须匹配一个非 . 的字符,导致单个字符根本不能符合要求;并且此方案遇到 #a 这样的 不以 . 开头的也会给通过,肯定是不行的

可视化图如下:

关于一条正则匹配规则的若干条方案讨论

方案2(错解)

^[^.]([A-Za-z0-9-_.]*[^.])?$

(大佬1提供)

此方案使用第一个 [^.] 满足非 . 开头,后面的使用分组结合,满足可0次1匹配,很优秀

但是发现此方案还有不足,就是非 . 开头的字符都满足要求,这样显示是不行的,因为 #a 这样的也能符合要求

可视化图如下:

关于一条正则匹配规则的若干条方案讨论

方案3(正解1)

^[A-Za-z0-9-_]+(\.+[A-Za-z0-9-_]+)*$

(大佬2提供)

此方案优秀,将需求整理为 ^a+(b+a+)*$ 的形式

以 (.+[A-Za-z0-9-_]+)* 这样组合的方式,尤其是中间的 .+ 完美适配 【不可以.结尾】这个规则

可视化图如下:

关于一条正则匹配规则的若干条方案讨论

方案4(正解2)

^(?!\.)[A-Za-z0-9-_.](?<!\.)$

(大佬3)提供

此方案非常优秀,这位大佬的写法是 ^(?!.) 和 (?<!.)$ 这样的结合,将反前瞻与^ 结合,将 反后顾与 $ 结合,而不是与内容结合,应该是这样的思路

但是貌似很多场合这种写法都不支持,比如在Linux下,不知道php中是否支持,因为同时的前瞻+后顾,但是此思路是非常优秀的

方案5 (错解)

(菜鸡本人提供)

^(?<!\.)[A-Za-z0-9-_.]+(?!\.)$

本以为前瞻+后顾能解决,没想到总是不能满足不以 . 开头或结尾,方案4的写法为本写法的高级版本

除此以外,上面的匹配如果要加上中文,只需要 [\x{4e00}-\x{9fa5}A-Za-z0-9-_] 这样的形式即可,加上 \x{4e00}-\x{9fa5}

果然还是集体的力量强大,感谢 QQ群【专精正则表达式】 434252251 各位群友提供的优秀思路

原创文章,作者:witersen,如若转载,请注明出处:https://www.witersen.com

(1)
witersen的头像witersen
上一篇 2022年8月6日 上午10:06
下一篇 2023年3月8日 下午6:40

相关推荐

  • 关于正则匹配的秃头问题

    1、为了切入这个问题,首先介绍一下问题背景: 下面为示例文本 2、问题来了 现在我要匹配 [color1] 所在分组的内容,按照下面的正则表达式写法 上面正则的图形化表示如下图 上…

    2022年7月2日
    1.3K0

发表回复

登录后才能评论