【问题标题】:JavaScript: Regex - Cannot start/end with punctuation, no repeating punctuationJavaScript:正则表达式 - 不能以标点符号开始/结束,没有重复的标点符号
【发布时间】:2016-02-27 06:13:44
【问题描述】:

我正在尝试创建一个正则表达式。规则是:

1) 仅限字母(大写和小写)、数字、句点 (.) 和下划线 (_)

2) 必须以字母或数字开头和结尾(即没有句点/下划线)

3) 一行中不能有多个标点符号,任何类型(没有 .. 或 ._ 或 _. 或 __ 或 .._. 等)

4) 必须包含至少 2 个字母(大写字母或小写字母或两者皆有,无所谓)

5) 不少于 3 个字符,不超过 25 个字符

到目前为止,我所拥有的是:

^((?!.*[\._]{2})[A-Za-z0-9\._]{3,25})$

这是接近的。我有规则 1、3 和 5,但无法弄清楚 2 和 4。

我以为

(([A-Za-z0-9]?)([A-Za-z0-9\._]+)([A-Za-z0-9]?)){3,25}

会得到规则 2,但它只是打破了它。

我已经为此工作了几个小时,但我找不到或想出的解决方案都不是我想要的。

非常感谢您提供对 Regex 语句的解释,但并非完全必要。

编辑 1

根据菜鸟的建议:

^((?!.*[\._]{2})(([\w\d\.]+)){3,25})$

编辑 2

有效:

1rockit.man
q3w
e4.45r.d.2
sp_am

(以及 3 到 25 个字符之间的任何其他字符,没有前导或重复的标点符号)

无效:

.ret.
123
12a
ret..wer
super_.duper
_petrat
petrat_

【问题讨论】:

  • 使用shorthand 运算符,如\w\d。更容易理解。 \w 还包括 _ 以便覆盖。
  • 您可能希望包含一些 validinvalid 匹配项以进行快速测试。
  • 1rockit.mane4.45r.d.2 根据条件 2 无效不能以非字母/数字开头或结尾。您可能想再次检查给定的条件或示例。
  • @noob 不能非字母非数字开头。即,必须以字母或数字开头和结尾。我会在帖子中说得更清楚
  • 好的。 non-letter/number 似乎令人困惑。

标签: javascript regex


【解决方案1】:

根据您的条件,我想出了以下正则表达式。它只是对您当前的正则表达式的修改。

正则表达式: ^(?=.*[A-Za-z].*[A-Za-z])([A-Za-z0-9]((?!.*[\._]{2})([\w\d\.]{1,23}))[A-Za-z0-9])$

说明:

  • 第一部分 (?=.*[A-Za-z].*[A-Za-z]) 检查整​​个字符串是否包含由 anything 分隔的 two 个字符(此处几乎就是这种情况)。 p>

  • 我在字符串的开头和结尾添加了检查,字符串应该是 letternumber

  • 除此之外,长度现在也会有所不同,因为计算第一个和最后一个字符,其余长度将只有 23 个字符

Regex101 Demo

【讨论】:

    【解决方案2】:

    根据规则构建正则表达式(按方便顺序):

    • 大写和小写 => 使用不区分大小写的标志//i
    • 字母、数字、下划线和句点 => [\w.]*
    • 3-25 个字符 => ^[\w.]{3,25}$
    • 不能以句点或下划线开头或结尾 => (?!^[\W_]|[W_]$)
      (注意大写\W 表示not \w
    • 不能连续包含 2 个标点符号 => (?![\W_]{2})
    • 检查每个位置的负前瞻 => (?:(?!...)[\w.]){3,25}
      (使用非捕获组 (?:) 而不是 (),因为我们不需要保存组)
    • 至少 2 个字母 => (?:.*[a-z]){2} 假设 i 标志
    • 进入前瞻(不消耗任何字符),以便我们可以检查多个条件 => (?=(?:...))

    最终的正则表达式文字:

    /^(?=(?:.*[a-z]){2})(?:(?!^[\W_]|[\W_]{2}|[\W_]$)[\w.]){3,25}$/i
    

    https://regex101.com/r/yK1cB3/5#javascript


    FTR:在支持x 标志的语言中(忽略正则表达式中的空格),您可以使其更具可读性(参见workaround for javascript):
    ^
    (?=
      (?:.*[a-z]){2}
    )
    (?:
       (?!^[\W_]|[\W_]{2}|[\W_]$)
       [\w.]
    ){3,25}
    $
    

    【讨论】:

    • 如何修改它以允许在开头和结尾使用标点符号(仅句点和下划线)?我尝试将中间部分更改为(?:(?![\W_]{2}$)[\w.]),这确实允许开始和结束标点,但它也允许连续使用多个标点。
    • 完美!谢谢你。 /^(?=(?:.*[a-z]){2})(?:(?![\W_]{2})[\w.]){3,25}$/i,对于其他可能想知道的人。
    【解决方案3】:

    你可以试试:

    ^(?=.*[a-zA-Z].*[a-zA-Z].*)[a-zA-Z0-9](?!.*[._]{2,}|.*[._]$)[._a-zA-Z0-9]{2,24}$
    

    或者,如果你更喜欢使用像 \w \d \s 这样的字符类,你可以使用:

    ^(?=.*[a-zA-Z].*[a-zA-Z].*)\w(?!.*[._]{2,}|.*[._]$)(\w|[._]){2,24}$
    

    http://regexr.com/3ct34

    【讨论】:

      【解决方案4】:

      参加你的谜语挑战。这是我的版本。也会有不错的表现:)

      /^(?=(?:.*?[a-z]){2})[a-z\d](?!.*?[._]{2})[\w.]{1,23}[a-z\d]$/i
      

      i flag 用于无大小写匹配,其中[a-z] 等效于 alpha [a-zA-Z]
      \w 是用于单词字符 [A-Za-z0-9_]short,因此 [\w.] 将匹配允许的字符。
      (?: 打开一个non capturing group,主要用于重复或交替(如果不需要组)。
      (?= (?! lookarounds 是在某个位置触发的零长度断言。

      • 规则 2:在^ 开始时需要一个[a-z\d],在$ 结束时需要一个
      • 规则 1 和 5:不少于 3 条,不超过 25 条,开始/结束相减[\w.]{1,23}
      • 规则 3:(?!.*?[._]{2}) 没有连续的标点符号被否定前瞻检查。
      • 规则 4:(?=(?:.*?[a-z]){2}) 至少检查了 2 个字母并采用正向前瞻。

      Check out demo at regex101

      【讨论】:

        猜你喜欢
        • 2015-10-25
        • 2013-05-12
        • 2012-07-27
        • 2017-02-03
        • 1970-01-01
        • 2013-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多