4

我想匹配所有满足以下规则的字符串-

  • 应该由小写字母和数字和破折号组成
  • 应该以字母或数字开头
  • 应以字母或数字结尾
  • 总字符串长度应至少为 3 且最多 20 个字符
  • dot.是可选的,不应该有两个或多个连续的点.
  • 破折号-是可选的,不应有两个或多个连续破折号-
  • .和破折号-不应该是连续的 // 字符串aaa.-aaabbb无效
  • 不允许下划线

我想出了这个正则表达式:

^[a-z0-9]([a-z0-9]+\.?\-?[a-z0-9]+){1,18}[a-z0-9]$

[a-z0-9] //should start/end with a letter or a number
([a-z0-9]+\.?\-?[a-z0-9]+){1,18}  //other rules

然而,它在某些情况下失败了 -

abcdefghijklmnopqrstuvwxyz //should fail total number of chars greater than 20  
aaa.-aaabbb //should fail as dot '.' and dash '-' are consecutive

谁能帮我纠正这个正则表达式?

4

2 回答 2

3

您可以通过前瞻断言来实现这一点:

^(?!.*[.-]{2})[a-z0-9][a-z0-9.-]{1,18}[a-z0-9]$

解释:

^                # Start of string
(?!              # Assert that the following can't be matched:
 .*              #  Any number of characters
 [.-]{2}         #  followed by .. or -- or .- or -.
)                # End of lookahead
[a-z0-9]         # Match lowercase letter/digit
[a-z0-9.-]{1,18} # Match 1-18 of the allowed characters
[a-z0-9]         # Match lowercase letter/digit
$                # End of string
于 2012-08-02T12:03:51.240 回答
1

我想出了这个方法,它使用类似于 Tim 的解决方案的负前瞻,但应用它的方式不同。因为它只在看到点或破折号时才会向前看,所以它可能不需要做太多的回溯,这可能会使它的执行速度稍微快一些。

^[a-z0-9]([a-z0-9]|([-.](?![.-]))){1,18}[a-z0-9]$

解释:

^                  # Start of string
[a-z0-9]           # Must start with a letter or number
(                  # Begin Group
   [a-z0-9]        # Match a letter or number
   |               # OR
   ([-.](?![.-]))  # Match a dot or dash that is not followed by a dot or dash
){1,18}            # Match group 1 to 18 times
[a-z0-9]           # Must end with a letter or number
$                  # End of string
于 2012-08-02T12:17:37.527 回答