【问题标题】:Regular Expression to check max of 2 digits,max of 4 alphabets in a alphanumeric string of length 6?正则表达式检查长度为 6 的字母数字字符串中最多 2 个数字,最多 4 个字母?
【发布时间】:2009-08-23 07:11:29
【问题描述】:

它应该与以下所有示例匹配。

aBCd22
a2b2CD
22aBcD

【问题讨论】:

  • “最大值”是多余的吗?应该正好是 2 位数字,正好是 4 个字母吗?
  • 不超过 2 个数字,不超过 4 个字母
  • 那么像 "a2" 或 "" 这样的东西会匹配吗?
  • 不,字符串的长度应该是 6,我已经给出了应该匹配的例子。
  • 嗯,它应该匹配这些例子 aBCd22 a2b2CD 22aBcD abcd22

标签: .net regex


【解决方案1】:

一个紧凑的版本,使用 positive lookahead 运算符:

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

解释:

(?=(.*[0-9]){2}) # asserts that you have 2 digits
(?=(.*[A-Za-z]){4}) # asserts that you have 4 characters
[A-Za-z0-9]{6} # does the actual matching of exactly 6 alphanumeric characters

一个简单的测试用例,用 Python 编写:

import re
rex = re.compile('(?=(.*[0-9]){2})(?=(.*[A-Za-z]){4})[A-Za-z0-9]{6}')
tests = ['aBCd22', 'a2b2CD', '22aBcD', 'asd2as', '', '201ABC', 'abcA213']
for test in tests:
print "'%s' %s" % 
       (test, "matched" if rex.match(test) != None else "didn't match")

输出:

'aBCd22' matched
'a2b2CD' matched
'22aBcD' matched
'asdas' didn't match
'' didn't match
'201ABC' didn't match
'abcA213' didn't match

【讨论】:

  • 干净、简单、有效。
  • 实际上,这只检查有两个数字和至少四个字母。无论如何它都可以工作,因为你不能有超过 2 个数字 + 4 个字母并且正好想出六个字符,但就解释而言...... :)
  • 一个用于准确验证x 数字和y 字母的工作正则表达式片段就像:/^(?=([^0-9]*[0-9]){x}$)(?=([^A-Za-z]*[A-Za-z]){y}$)/ 但如果你问我,整个想法非常聪明。如果您必须 使用一些只接受正则表达式进行验证的工具,可以。但是,如果您不需要这样做,请说出您的意思。 :)
  • 谢谢,正是我需要的
  • 假设如果我希望它在 'a1' 或 'a11' 或 'ab11' 的情况下匹配,你将如何放置 [A-Za-z0-9]{6} 的范围你使它成为 [A-za-z0-9]{1,6} 并且对于使用 (?=(.*[0-9]){1,2}) 的数字断言,它仍然接受 'a111'
【解决方案2】:

我不知道你是否可以只用一个正则表达式,但你当然可以用两个。也就是说,在这项任务中使用正则表达式似乎有点过分。

在 Perl 中,我会这样做:

m/\d.*\d/ # match exactly 2 numeric characters
  &&
m/(?:[[:alpha:]].*){4}/ # match exactly 4 alpha characters

【讨论】:

  • 非常聪明。您可能还需要检查长度?
  • 您的 \d.*\d 想法给了我自己答案的灵感。谢谢。 =]
  • 你的匹配没有锚定,所以再次,他们只检查至少两个数字和四个字母存在于字符串的某处。
【解决方案3】:

我不认为正则表达式是这里的方法。

当然,您可以创建每个可能允许的数字和字母顺序的交替,但您需要 6 * 5 = 30 个。

我不知道使用正则表达式进行计数的任何方法。

您可以使用正则表达式来检查您是否有 6 个字母数字字符,然后手动进行计数。

【讨论】:

    【解决方案4】:

    也许是这个?

    (?=[a-z]*\d?[a-z]*\d?)
    (?![a-z]*\d[a-z]*\d[a-z]*\d)
    (?=\d*[a-z]?\d*[a-z]?\d*[a-z]?\d*[a-z]?)
    (?!\d*[a-z]\d*[a-z]\d*[a-z]\d*[a-z]\d*[a-z])
    [\da-z]{2,6}
    

    它的工作原理是确保所选内容有零、一个或两个数字(第一个前瞻),但不超过两个(第二个前瞻)。类似地,它检查零到四个字母(第三个前瞻)但不超过四个(第四个前瞻)。第五行匹配一到六个字符。

    如果您只想匹配单词,请将其包装在 \b 中。

    编辑:现在您添加了匹配长度为六个字符的要求。只需要稍作修改:

    (?=[a-z]*\d[a-z]*\d)
    (?![a-z]*\d[a-z]*\d[a-z]*\d)
    (?=\d*[a-z]\d*[a-z]\d*[a-z]\d*[a-z])
    (?!\d*[a-z]\d*[a-z]\d*[a-z]\d*[a-z]\d*[a-z])
    [\da-z]{6}
    

    【讨论】:

    【解决方案5】:

    这个正则表达式应该这样做:

    ^(?=[a-zA-Z]*\d[a-zA-Z]*\d[a-zA-Z]*$)(?=\d*[a-zA-Z]\d*[a-zA-Z]\d*[a-zA-Z]\d*[a-zA-Z]\d*$).*
    

    或更紧凑:

    ^(?=[a-zA-Z]*(?:\d[a-zA-Z]*){2}$)(?=\d*(?:[a-zA-Z]\d*){4}$).*
    

    【讨论】:

    • 嘿,这看起来很像我的。 =]
    【解决方案6】:
    ^((?<digit>\d)|(?<alpha>[a-zA-Z])){6}
    (?<-alpha>){4}(?(alpha)(?!))
    (?<-digit>){2}(?(digit)(?!))$
    

    这将匹配 6 个字符,正好是 2 个数字和 4 个字母。它通过抓取任何它可以做到的,然后通过将结果从计数器堆栈中弹出来计算结果。查看this链接了解更多详情。

    • (?){4} 表示“从堆栈中弹出 4 个匹配项”。如果不能弹出,则失败
    • (?(alpha)(?!)) 表示“如果有 alpha 匹配,则查找 (?!),但总是失败。
    • ^ 和 $ 匹配开头和结尾

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-13
      • 1970-01-01
      • 2018-11-03
      • 1970-01-01
      相关资源
      最近更新 更多