【问题标题】:Match exactly one of each from set of characters匹配一组字符中的每一个
【发布时间】:2016-03-14 14:15:30
【问题描述】:

我正在尝试匹配一组特定的字符,但每个字符只有 1 个且只有 1 个。

例如,如果集合是[abcd],我想以任意顺序匹配包含这些确切字符的字符串。

abcd  - true
bcad  - true
abc   - false (need all characters)
abbd  - false
abcdd - false

据我目前了解,使用 RegEx 实现这一目标并没有简单的方法,但没有一个答案足够确凿。

【问题讨论】:

  • 您使用什么语言?在你的情况下没有 pattern,我怀疑正则表达式是否是最好的方法(当然你可以在所有组合上使用交替.. 但这太可怕了)。

标签: regex


【解决方案1】:

我会想到capturing 并使用lookahead 来检查相同的字符是否不在前面。

\b(?:([abcd])(?!\w*?\1)){4}\b
  • (?: 打开一个 non capture group 进行重复
  • \b 匹配 word boundary
  • ([abcd]) 捕获 [abcd] 之一
  • (?!\w*?\1) 检查捕获的字符是否不在前面,中间有任何数量的 \w
  • {4}\b 4 次直到另一个单词边界

See demo at regex101 (仅在您的正则表达式中提供前瞻功能时才有效)

【讨论】:

  • 我认为这是 OP ++ 的最佳正则表达式解决方案
【解决方案2】:

您可以对每个字符使用前瞻来断言 char 在您的正则表达式中只出现一次。

例如对于您的输入字符abcd 生成这个正则表达式:

^(?=[^a]*a[^a]*$)(?=[^b]*b[^b]*$)(?=[^c]*c[^c]*$)(?=[^d]*d[^d]*$)

RegEx Demo

^(?=[^a]*a[^a]*$) 将断言a 在输入中仅出现一次。以此类推其他字符b,c,d

【讨论】:

  • 如果输入是abcdefghijklmnopqrstuvwxyz 怎么办?
  • 它显然会失败,因为输入中不存在x,y,z 等,但如果输入有太多字符,那么生成的正则表达式也可能太长
  • 它看起来不漂亮,但应该可以有效地完成工作。
【解决方案3】:

您要解决的问题是检查字符串是否是“abcd”的排列。

您不想对遇到的每个问题都使用正则表达式。当您拥有 模式 时,它会非常有用且功能强大。检查字符串是否是“abcd”的排列并不是真正的“模式”。

最好的方法是利用语言的强大功能并根据您可用的功能构建解决方案。

【讨论】:

    【解决方案4】:

    只是使用 grep 的一个不起眼的贡献:

    grep -Px '[abcd]{4}' | grep -vP '(.).*\1'
    
    • 获得 4 的序列 [abcd]
    • 并删除连续重复的行

    【讨论】:

      【解决方案5】:

      请参阅bobble bubble's excellent answer 了解真正的正则表达式解决方案(有时这是必要的)。这个答案使用排序和字符串相等而不是单个正则表达式:

      var set = 'bcad'; // in any order
      var tests = [
        'abcd',  // true
        'bcad',  // true
        'abc',   // false (need all characters)
        'abbd',  // false
        'abcdd', // false
      ];
      
      var setSorted = set.split('').sort().join();
      
      for (var i = 0; i < tests.length; i++) {
        var pass = setSorted == tests[i].split('').sort().join();
        console.log(`${tests[i]}: ${pass}`);
      }

      【讨论】:

        猜你喜欢
        • 2023-03-29
        • 2018-04-07
        • 1970-01-01
        • 1970-01-01
        • 2015-03-25
        • 2023-02-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多