【问题标题】:RegEx to find words with characters正则表达式查找带有字符的单词
【发布时间】:2017-05-10 16:34:22
【问题描述】:

我在这里找到了许多问题的答案,但这次我被困住了。我已经查看了 100 多个问题,但没有找到解决我问题的答案,所以我希望得到您的帮助:D

考虑以下单词列表:

iris
iridium
initialization

当我完全使用字符 u、i、i 查找时,如何使用正则表达式在此列表中查找单词?我希望正则表达式能够找到“铱”,只是因为它是列表中唯一有两个 i 和一个 u 的单词。

我尝试过的

我一直在这里和其他地方搜索,但没有找到任何对我有帮助的东西。

 [i].*[i].*[u]

与预期的一样匹配铱,而不是虹膜或初始化。但是,字符 i、i、u 必须在单词中按该顺序排列,这可能是,也可能不是。所以尝试不同的顺序

 [u].*[i].*[i]

这与铱不匹配(但我希望它匹配,铱包含 u、i、i)并且我被卡住了怎么做才能匹配。有什么想法吗?

我知道我可以尝试所有序列(在上面的示例中,它会是 iiu; iui; uii)但是当我正在寻找更多的字符(比如 6,tnztii 将匹配初始化)。

 [t].*[n].*[z].*[t].*[i].*[i]
 [t].*[z].*[n].*[t].*[i].*[i]
 [t].*[z].*[n].*[i].*[t].*[i]
 ..... (long list until)
 [i].*[n].*[i].*[t].*[z].*[t] (the first matching sequence)

有没有办法使用正则表达式来查找单词,而不管字符的顺序如何?

【问题讨论】:

  • 正则表达式对此不太好。你真的需要它们吗?
  • 您可以单独匹配字符并使用编程逻辑来验证所有字符是否匹配。

标签: regex


【解决方案1】:

我认为没有办法用正则表达式来解决这个问题,它不会以非常复杂的表达式结尾 - 使用 LookForward 和 LookBehind 表达式可能是可能的,但我认为如果你简单地以编程方式解决这个问题,它可能会更快且更少混乱.

通过空格将字符串截断,然后遍历所有单词并计算字符出现在该单词中的实例。为了加快速度,请丢弃所有长度小于字符数要求的单词。

【讨论】:

    【解决方案2】:

    这是一项学术练习,还是您可以使用多个正则表达式?有没有一种语言围绕着它?做你想做的最简单的方法是有一个只匹配i 或u 的正则表达式,然后检查(计数)匹配项。使用python,它可能是单行的。你在用什么?

    您尚未了解的部分是单词中可能还有其他 i 或 u。所以不是匹配.*,而是匹配[^iu]。

    【讨论】:

      【解决方案3】:

      我会这样做:

      Array.prototype.findItemsByChars = function(charGroup) {
          console.log('charGroup:',charGroup);
          charGroup = charGroup.toLowerCase().split('').sort().join('');
          charGroup = charGroup.match(/(.)\1*/g);
          for (var i = 0; i < charGroup.length; i++) {
              charGroup[i] = {char:charGroup[i].substr(0,1),count:charGroup[i].length};
              console.log('{char:'+charGroup[i].char+' ,count:'+charGroup[i].count+'}');
          }
          var matches = [];
          for (var i = 0; i < this.length; i++) {
              var charMatch = 0;
              //console.log('word:',this[i]);
              for (var j = 0; j < charGroup.length; j++) {
                  try {
                      var count = this[i].match(new RegExp(charGroup[j].char,'g')).length;
                      //console.log('\tchar:',charGroup[j].char,'count:',count);
                      if (count >= charGroup[j].count) {
                          if (++charMatch == charGroup.length) matches.push(this[i]);
                      }
                  } catch(e) { break };
              }
          }
          return matches.length ? matches : false;
      };
      
      var words = ['iris','iridium','initialization','ulisi'];
      var matches = words.findItemsByChars('iui');
      console.log('matches:',matches);
      

      编辑:如果您需要任何解释,请告诉我。

      【讨论】:

        【解决方案4】:

        我知道这是一篇很老的帖子,但我发现这个话题很有趣,并认为有一天人们可能会寻找类似的答案。

        所以目标是以任意顺序将所有单词与一组特定字符匹配。有一种使用前瞻的简单方法:
        \b(?=(?:[^i\W]*i){2})(?=[^u\W]*u)\w+\b

        它的工作原理如下:

        我们对每个要匹配的字母使用一个前瞻 (?=...)
        在此,我们输入[^x\W]*x,其中 x 是必须存在的字母。
        然后我们让这个模式出现 n 次,其中 n 是 x 必须出现在第一个单词中的次数,使用 (?:...){n}

        字母 x 必须在单词中出现 n 次的结果正则表达式为 (?=(?:[^x\W]*x){n})
        然后,您所要做的就是为每个字母添加此模式并在末尾添加 \w+ 以匹配单词!

        【讨论】:

          猜你喜欢
          • 2017-11-02
          • 2016-02-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多