regex - 确定行是否包含 1-4 个特定字符的正则表达式

标签 regex

不确定最好的表达方式,所以我只举一个例子。假设我有字符 a,b,c,d .我想接受以任何顺序包含 0 或 1 个字符的任何字符串。字符串如 "ab" "abcd" "dcab"都是可以接受的。是否可以仅使用正则表达式来做到这一点?

我唯一想到的是((a|b|c|d){0,1}){0,4} .但是,这不起作用,因为它会接受诸如“aaaa”之类的字符串。

最佳答案

问题似乎很简单。但事实并非如此。干得好,

^([abcd])(?:(?!\1)([abcd]))?(?:(?!\1|\2)([abcd]))?(?:(?!\1|\2|\3)([abcd]))?$

DEMO

减少了一个,
^([abcd])((?!\1)[abcd])?((?!\1|\2)[abcd])?((?!\1|\2|\3)[abcd])?$

DEMO

图案说明:
  • ^断言我们处于开始阶段。
  • ([abcd])第一个字符必须是字符类(a 或 b 或 c 或 d)中的任何一个。而第一个字符是通过捕获组捕获的。
  • (?!\1)[abcd]第二个字符必须是字符类中的任何字符,但不能与第一个字符相似。而这个角色被抓获 ((?!\1)[abcd])?我们将整体设为可选。如果存在第二个字符,则它必须满足上述条件。
  • ((?!\1|\2)[abcd])? char 类中的任何字符,但不是第一个或第二个字符。该角色已被捕获,我们将其设为可选。
  • ((?!\1|\2|\3)[abcd])? char 类中的任何字符,但不是第一个、第二个或第三个字符。该角色已被捕获,我们将其设为可选。
  • $断言我们到了最后。


  • ^(?:(?!(.).*\1)[abcd])+$
    

    图案说明:
  • (?!(.).*\1)负前瞻断言字符不会重复。
  • (?:(?!(.).*\1)[abcd])+现在,仅当没有重复字符时,它才会匹配字符类(a 或 b 或 c 或 d)中的一个或多个字符。所以它最多只能匹配四个字符(1 到 4)。

  • DEMO



    通过PCRE动词(*SKIP)(*F) ,
    ^.*(.).*\1.*$(*SKIP)(*F)|^[abcd]+$
    

    图案说明:
  • ^.*(.).*\1.*$匹配所有具有重复字符的行。
  • (*SKIP)(*F)使之前的匹配失败。也就是说,正则表达式匹配标记将在所有行上,除了具有重复字符的行。现在它尝试匹配 | 右侧的模式运算符在没有任何重复字符的行上。
  • ^断言我们处于开始阶段。
  • [abcd]+来自字符类的任何字符一次或多次。因为我们已经跳过了所有有重复字符的行,所以它不会匹配 ababba
  • $断言我们到了最后。

  • DEMO

    关于regex - 确定行是否包含 1-4 个特定字符的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25954779/

    相关文章:

    ruby-on-rails - 正则表达式 - 除 1-9 或 a-zA-Z 之外的任何可打印字符

    ios - 如何在 NSString 中捕获多个特殊指示的 **characters** 并在它们之间加粗?

    php - 如何在 PHP 中使用正则表达式匹配 0 到 255 之间的数字?

    Java正则表达式在两个模式之间插入单个字符

    javascript - 如果没有组返回结果,如何构建不返回空字符串的正则表达式

    regex - 将姓氏拆分到新行

    python - 从 HTML 中删除 Script 标签和 on 属性

    regex - 使用 Perl 构建首字母缩略词查找器正则表达式

    regex - 用 SED 或 AWK(或其他有效的方法)替换日期 - Linux 正则表达式

    java - 理解 Java 正则表达式