【问题标题】:regex: find all words with certain letters but not other正则表达式:查找具有某些字母但不是其他字母的所有单词
【发布时间】:2015-04-09 04:17:52
【问题描述】:

谁能帮帮我:

我需要从包含字母 [t OR d] AND [k OR c] 但不包含任何 [s,z,n,m] 的列表中查找所有单词

我想出了第一部分,但不知道如何包含停止列表:

\w*[t|d]\w*[k|c]\w*

用 Python 表示法

提前谢谢你

【问题讨论】:

  • 一个示例,您的预期结果会有所帮助
  • if (re.search('[td]', input) or re.search('[kc]', input)) and not re.search('[sznm]', input)
  • 请注意,您当前的正则表达式只会找到 td 出现在 kc 之前的单词 - 这就是您想要的吗?
  • [t OR d] 是什么意思? tried 会匹配吗?

标签: python regex letters


【解决方案1】:
s = "foobar foo".split()

allowed = ({"k", "c"}, {"r", "d"})
forbid = {"s","c","z","m"}

for word in s:
    if all(any(k in st for k in word) for st in allowed) and all(k not in forbid for k in word):
        print(word)

或者使用带有 set.intersection 的列表组合:

words = [word for word in s if all(st.intersection(word) for st in allowed) and not denied.intersection(word)]

【讨论】:

    【解决方案2】:

    基于Padraic的回答

    编辑我们都错过了这个条件

    [t 或 d] 与 [k 或 c]

    所以 - 相应地修复

    s = "detected dot knight track"
    
    allowed = ({"t","d"},{"k","c"})
    forbidden = {"s","z","n", "m"}
    
    for word in s.split():
        letter_set = set(word)
        if all(letter_set & a for a in allowed) and letter_set - forbidden == letter_set:
            print(word)
    

    结果是

    detected
    track
    

    【讨论】:

    • 谢谢,从长远来看,正则表达式是不可行的想法
    【解决方案3】:

    我真的很喜欢@padraic-cunningham 的回答,它没有使用 re,但这里有一个模式,它可以工作:

    pattern = r'(?!\w*[sznm])(?=\w*[td])(?=\w*[kc])\w*'
    

    积极的(?=...) 和消极的(?!...) 前瞻断言在python.org 上有详细记录。

    【讨论】:

      【解决方案4】:

      您需要使用环视。

      ^(?=.*[td])(?!.*[sznm])\w*[kc]\w*$
      

      即,

      >>> l = ['fooktz', 'foocdm', 'foobar', 'kbard']
      >>> [i for i in l if re.match(r'^(?=.*[td])(?!.*[sznm])\w*[kc]\w*$', i)]
      ['kbard']
      

      【讨论】:

        【解决方案5】:

        如果您需要在k or c 之前出现t or d,请使用:[^sznm\s\d]*[td][^sznm\s\d]*[kc][^sznm\s\d]*

        [^sznm\s\d] 表示除z, n, m, s、空白字符 (\s) 或数字 (\d) 之外的任何字符。

        【讨论】:

        • [^sznm] 不等于 除了 s、z、n、m 以外的所有字母 这意味着单词可以包含符号空格和 ...
        • 是的,因此是精确度,但我添加了空格和数字
        • 好的,新的建议模式更容易接受,但不是例外标志。
        • 您的解决方案正在运行,但它使整体有点复杂(这只是我的问题),所以我决定避免使用正则表达式 - 谢谢
        【解决方案6】:

        使用此代码:

        import re
        re.findall('[abcdefghijklopqrtuvwxy]*[td][abcdefghijklopqrtuvwxy]*[kc][abcdefghijklopqrtuvwxy]*', text)
        

        【讨论】:

          【解决方案7】:

          您可以使用 2 个步骤。先找到 t|d AND k|c,然后过滤掉不想要的字母。

          既然你说你想出了第一部分,那就是第二部分:

          matches = [i for i in matches if not re.search(r'[sznm]', i)]    
          print(matches) 
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-10-14
            相关资源
            最近更新 更多