限制正则​​表达式中的字母字符数

时间:2010-06-09 14:56:41

标签: regex

我一直在努力弄清楚如何最好地做这个正则表达式。

以下是我的要求:

  • 最多8个字符
  • 只能是字母数字
  • 最多只能包含三个字母字符[a-z](零字母字符有效)

任何想法都会受到赞赏。

这是我到目前为止所做的,但它只查找连续的字母字符:

^(\d|([A-Za-z])(?!([A-Za-z]{3,}))){0,8}$

4 个答案:

答案 0 :(得分:7)

我会这样写:

^(?=[a-z0-9]{0,8}$)(?:\d*[a-z]){0,3}\d*$

它有两部分:

  • (?=[a-z0-9]{0,8}$)
    • Looksahead并在字符串末尾匹配最多8个字母数字
  • (?:\d*[a-z]){0,3}\d*$
    • 基本上允许在[a-z]
    • 中注入最多3个\d*

Rubular

rubular.com

12345678    // matches
123456789
@(#*@$
12345       // matches
abc12345
abcd1234
12a34b5c    // matches
12ab34cd
123a456     // matches

替代

我认为正则表达式是最好的解决方案,但由于字符串很短,因此通过以下两个步骤执行此操作会更具可读性:

  • 必须与[a-z0-9]{0,8}
  • 相匹配
  • 然后,删除所有\d
    • 现在必须为<= 3

答案 1 :(得分:2)

您是否必须在一个正则表达式中执行此操作?使用标准正则表达式 可以做到这一点,但正则表达式会相当漫长而复杂。您可以使用某些Perl扩展程序做得更好,但根据您使用的语言,它们可能支持也可能不支持。最干净的解决方案可能是检查字符串是否匹配:

^[A-Za-z0-9]{0,8}$

但不匹配:

([A-Za-z].*){4}

即。它是一个最多8个字符(第一个正则表达式)的字母字符串,但不包含4个或更多字母字符(可能由其他字符分隔(第二个正则表达式)。

答案 2 :(得分:1)

/^(?!(?:\d*[a-z]){4})[a-z0-9]{0,8}$/i

说明:

  • [a-z0-9]{0,8}最多匹配8个字母数字。
  • 在匹配发生之前,应将放置在前面。
  • (?:\d*[a-z])在任何地方都匹配1个字母。 {4}使计数为4.因此,当可以找到4个字母时,这会使正则表达式无法匹配(即将计数限制为≤3)。

利用这样的正则表达式更好 。假设你使用这个解决方案,你确定在1年后重新访问它时你会知道代码在做什么吗?更明确的方法是按规则检查,例如

if len(theText) <= 8 and theText.isalnum():
   if sum(1 for c in theText if c.isalpha()) <= 3:
      # valid

答案 3 :(得分:0)

最简单的方法是分多步:

  1. 针对/^[a-z0-9]{0,8}$/i测试字符串 - 字符串最多为8个字符且仅包含字母数字
  2. 复制字符串,删除所有非字母字符
  3. 查看结果字符串的长度是否为3或更短。
  4. 如果您想在一个正则表达式中执行此操作,可以使用以下内容:

    /^(?=\d*(?:[a-z]?\d*){0,3}$)[a-z0-9]{0,8}$/i

    查找长度为0到8(^[a-z0-9]{0,8}$)之间的字母数字字符串,但首先使用前瞻((?=\d*(?:[a-z]?\d*){0,3}$))来确保字符串 最多有3个字母字符。