不包含相邻句点 (.)、连字符 (-) 或下划线 (_) 的名称的正则表达式

Regex for name not containing adjacent periods (.), hyphens (-), or underscores (_)

我一直在为符合以下条件的名称开发正则表达式:

  1. 仅包含 ASCII 字母(a-zA-Z)、数字(0-9)、句点(.)、下划线(_),或破折号 (-)

  2. 以字母或数字开头,以字母或数字结尾

  3. 介于 3 到 128 个字符之间

  4. 没有相邻的句点、下划线或破折号。像 my-_namespace 这样的名字 和 my--namespace 无效。

到目前为止,我想出了以下模式:

^[a-zA-Z0-9](?!.*--)[a-zA-Z0-9._-]{1,126}[A-Za-z0-9]$

这适用于相邻的连字符。如何合并无相邻连字符、下划线和点的功能?

^[a-zA-Z0-9]([0-9A-Za-z]|[\._-](?![\._-])){1,126}[a-zA-Z0-9]$

这部分避免了重复的字符[\._-](?![\._-])

所以你最终会在字符、数字和单个点、单个下划线和单个破折号之间交替

尝试用下划线和点做同样的 (?!.*--) 否定前瞻?像这样:

^[a-zA-Z0-9](?!.*--)(?!.*\.\.)(?!.*__)[a-zA-Z0-9._-]{1,126}[A-Za-z0-9]$

一种方法是在正则表达式的开头放置禁止此类组合的否定前瞻。

^(?!.*[\._-]{2})[a-zA-Z0-9][a-zA-Z0-9\._-]{1,126}[a-zA-Z0-9]$

Debuggex Demo

您可能会过度使用前瞻和非捕获组:

  1. 使用正向先行检查整个字符串的长度。
  2. 使用负先行检查非重复分隔符。

^(?=.{3,128})[0-9A-Za-z](?:[0-9A-Za-z]|(?:[-_\.](?![-_\.])))+[0-9A-Za-z]$
       ^           ^            ^            ^       ^            ^
       |           |            |            |       |            |
     Length     Starts      Either a       Or a     but          Ends
     check       with        letter      sepatator  not          with
                letter                            followed      letter
                                                 by another
                                                 separator