问题描述
我正在尝试编写一个词汇游戏。
我正在使用正则表达式来隐藏我必须猜测的单词。我对正则表达式使用的语法不满意 - 除了简单的例子,我很困惑。
以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)))
结果:['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 返回捕获的文本。