re.findall() 除了某些文本之外的所有内容

问题描述

我正在尝试编写一个词汇游戏。

我正在使用正则表达式来隐藏我必须猜测的单词。我对正则表达式使用的语法不满意 - 除了简单的例子,我很困惑。

chosen_word

为例
'TO CRANK (STH) UP'

使用正则表达式,我设法隐藏了关键字,并且我有 hidden_​​word 如下:

TO _ _ _ _ _   (STH)  _ _ 

现在,我首先尝试创建一个包含所有隐藏字母的列表,这样我就可以根据用户的要求一次显示一个在这个特定示例中,我希望列表包含字符串中的每个隐藏字母,即除首字母 'TO' 和括号中的 STH 之外的每个字母。本质上,我想得到:

C,R,A,N,K,U,P 

我一直在尝试使用这个 RegEx:

chosen_word = "TO CRANK (STH) UP"
hidden_letters = re.findall(r"(?!TO|STH)[A-Z]",chosen_word)

但我得到的是:

O,C,T,H,P

也就是说,它只排除指定单词的第一个字母(T 代表“TO”,S 代表“STH”)。但是如果添加括号将它们一起捕获:

hidden_letters = re.findall(r"(?!(TO)|(STH))[A-Z]",chosen_word)

我得到一个奇怪的结果:一个逗号列表,当原始字符串中没有逗号时。

(",",")

发生了什么?我如何获得捕捉我想要的东西的方法

此外,一旦我进行了排序,我的想法是随机选择这些字母之一,为此我使用随机库并随机选择一个字母,将其从列表中删除以避免在不同轮次中重复:

if first_reveal == True:
    hidden_letters = re.findall(r"(?!TO|STH)[A-Z]",chosen_word)
    first_reveal = False
                  
letter = random.choice(hidden_letters)
                    
hidden_letters.remove(letter)

如果我把正则表达式弄对了,下划线和字母会精确地相互映射。也就是说,假设我的代码随机选择字母“K”,即列表的第 5 个字母,我希望它替换隐藏单词中的第 5 个下划线。但我不知道如何开始!有什么提示吗?

非常感谢!

解决方法

使用

import re
chosen_word = "TO CRANK (STH) UP"
hidden_letters = re.findall(r"(?:\bTO\b|\(STH\))|([A-Z])",chosen_word)
print(list(filter(None,hidden_letters)))

Python proof

结果['C','R','A','N','K','U','P']

正则表达式

(?:\bTO\b|\(STH\))|([A-Z])

说明

--------------------------------------------------------------------------------
  (?:                      group,but do not capture:
--------------------------------------------------------------------------------
    \b                       the boundary between a word char (\w)
                             and something that is not a word char
--------------------------------------------------------------------------------
    TO                       'TO'
--------------------------------------------------------------------------------
    \b                       the boundary between a word char (\w)
                             and something that is not a word char
--------------------------------------------------------------------------------
   |                        OR
--------------------------------------------------------------------------------
    \(                       '('
--------------------------------------------------------------------------------
    STH                      'STH'
--------------------------------------------------------------------------------
    \)                       ')'
--------------------------------------------------------------------------------
  )                        end of grouping
--------------------------------------------------------------------------------
 |                        OR
--------------------------------------------------------------------------------
  (                        group and capture to \1:
--------------------------------------------------------------------------------
    [A-Z]                    any character of: 'A' to 'Z'
--------------------------------------------------------------------------------
  )                        end of \1

注意:如果正则表达式模式中包含捕获组,则 re.findall 返回捕获的文本。