正则表达式。20个字母和最多2个(. - _)

3
我正在尝试为HTML输入字段构建正则表达式模式,该模式仅允许最多20个字母和数字的组合,其中只能有最多两个破折号(-)、下划线(_)和句点(.)。因此,允许使用两个符号,任何数量的字母和数字,它们的组合必须在4到20之间。这种情况下的模式是什么?一个示例(不起作用)的版本可能是[A-Za-z0-9([\._-]{0,2})]{4,20}。
解决方案: 我决定采用@pascalhein @Honore Doktorr的答案,使用前瞻。最终的模式是^(?=[A-Za-z0-9]*([._-][A-Za-z0-9]*){0,2}$)[A-Za-z0-9._-]{4,20}$。

2
你能提供你的任何尝试吗?请同时提供有效和无效输入文本的示例。 - Wiktor Stribiżew
可能是密码强度的正则表达式的重复。 - Gyrocode.com
类似于 [A-Za-z0-9([\._-]{0,2})]{4,20} 的东西。 - user3254198
如果您提供示例输入字符串,将更快地获得帮助。另外,您所说的“最多2个”是指零个、一个还是两个? - Wiktor Stribiżew
2个回答

5
您可以在开头使用预查来验证长度:
^(?=.{4,20}$)

接着,分别列出正则表达式允许的所有情况:

[A-Za-z0-9]* (no special chars)

[A-Za-z0-9]*[._-][A-Za-z0-9]* (one special char)

[A-Za-z0-9]*[._-][A-Za-z0-9]*[._-][A-Za-z0-9]* (two special chars)

它不是很美观,但我相信它应该能够工作。这是最终表达式:

^(?=.{4,20}$)([A-Za-z0-9]*|[A-Za-z0-9]*[._-][A-Za-z0-9]*|[A-Za-z0-9]*[._-][A-Za-z0-9]*[._-][A-Za-z0-9]*)$

编辑:

其实用前瞻来测试特殊字符的数量可能更好:

^(?=[A-Za-z0-9]*([._-][A-Za-z0-9]*){0,2}$)[A-Za-z0-9._-]{4,20}$

非常优雅!我试图回答这个问题,但是我卡在了如何限制总字符串长度同时允许灵活数量的字母数字字符上。解释得很好。 - Joe DeRose
1
@pascalhein:或者使用否定预查断言,断言不超过两个特殊字符,(?!(?:.*[-_.]){3,}。完整表达式为 ^(?=.{4,20}$)(?!(?:.*[-_.]){3,})[-_.a-zA-Z0-9]*$示例 - Honore Doktorr
这正是我所需要的,感谢您的支持 :) - user3254198
@celerno 我在regexr.com上测试了,但你展示的内容有问题吗?据我理解,它不应该匹配,因为它包含4个特殊字符,而只允许2个。 - pascalhein

0

我鼓励你在有能够实现你想要达到的目的的函数时,尽量不要使用正则表达式。

我给初学者的建议是,对于单一目的,可以使用正则表达式;但如果有多个目的,则需要使用多个正则表达式。

回答你的问题:

  • 1 从头到尾匹配你的有效字符。

    var 1stregex = /^[A-Za-z0-9._-]{4,20}$/;

  • 2 计数必须为0到2,在JavaScript中是通过.match().length实现。

    var 2ndregex = /([._-])/;

    if(myText.match(1stregex) && myText.match(2ndregex).length <=2) { isvalid=true; }


我能理解你的想法,但是由于我正在尝试使用HTML的pattern标签来获得更多支持并避免编写实际的验证代码,所以我决定使用正则表达式。 - user3254198
有时候,从代码的简洁性和时间成本考虑,写几行代码是更好的选择。这是我的观点。 - celerno

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接