替换字符串的第 n 个字符(RegEx 与否)
replace the nth character of a string (RegEx or not)
我正在尝试编写一个词汇游戏。先声明一下,我是一个彻头彻尾的菜鸟程序员!
我正在使用正则表达式来隐藏一个我必须猜测的词。
以chosen_word为例:
'TO CRANK (STH) UP'
使用正则表达式,我设法隐藏了关键字,并且 hidden_word 如下:
TO _ _ _ _ _ (STH) _ _
使用 RegEx findall() 和 filter() 方法我得到了 hidden_letters:
['C', 'R', 'A', 'N', 'K', 'U', 'P']
我们现在的想法是从这个列表中随机选择一个字母来显示给用户:
chosen_letter = random.choice(hidden_letters)
n = hidden_letters.index(chosen_letter) + 1
现在所选字母的 n 漂亮地映射到 hidden_word 中相应的下划线。例如,如果游戏随机选择了字母 'R',那么 n 将是 '2',而在 hidden_word这个字母的位置在第2个下划线。
我现在卡在这个阶段了。我想用 chosen_letter[=59= 替换 nth 下划线 hidden_word ].我正在考虑使用 .replace() 方法或 RegEx re.sub() 方法,但我没有不知道如何开始。
有人可以给我提示吗?
非常感谢!!
我会以不同的方式处理这个问题:
每个时间点的状态定义为:
- 完整短语(待猜),
- 一组隐藏词,
- 到目前为止猜到的字母(或向用户透露)。
您可以使用这三个量定义一个 show()
函数:
def show(phrase, hidden_words, letters_guessed):
parts = [
''.join([
c if c in letters_guessed else '-' for c in w
]) if w in hidden_words else w
for w in phrase.split()
]
return ' '.join(parts)
有了这个,您可以编写测试,包括 doctests。这将使您的代码更易于记录、调试、测试和使用。
一些示例(可以作为文档测试包含在 show
的文档字符串中):
phrase = 'TO PIPE (STH) UP AND PIPE DOWN'
hidden_words = {'PIPE', 'UP'}
>>> show(phrase, hidden_words, {})
'TO ---- (STH) -- AND ---- DOWN'
>>> show(phrase, hidden_words, set('I'))
'TO -I-- (STH) -- AND -I-- DOWN'
>>> show(phrase, hidden_words, set('PI'))
'TO PIP- (STH) -P AND PIP- DOWN'
考虑到您是新手,我想把我的帽子扔进去,不使用正则表达式并尝试解释。也许只有在你开始之后才阅读这篇文章。您的问题标题可以这样回答:
def replace_nth_char(string, n, replacement):
n -= 1
l_string = list(string)
l_string[n] = replacement
return ''.join(l_string)
它将字符串转换为可以用索引替换的字母列表 n
,然后将其连接起来。
我还尝试了其余部分,向您展示了更多 python 选项。
在管理状态时,您可能需要考虑 using a class。它可以帮助您将所有功能和属性打包到一个 object 中,目的是玩您的词汇游戏。我建议调查一下。这是游戏的一个:
import random
class VocabularyGame():
def __init__(self, chosen_words, hidden_words):
self.chosen_words = chosen_words
self.hidden_words = hidden_words
self.hidden_letters = list(set(''.join(words)))
self.masked_sentence = self.mask_words(chosen_words, hidden_words)
print(f"Game start: {self.masked_sentence}")
def mask_words(self, sentence, masks):
return ' '.join(['_'*len(w) if w in masks else w for w in sentence.split(' ')])
def try_letter(self, letter=None):
if letter is None:
letter = random.choice(self.hidden_letters)
self.masked_sentence = ''.join(
[c if c== letter else m for m, c in zip(self.masked_sentence, self.chosen_words)]
)
self.hidden_letters = [l for l in self.hidden_letters if l != letter]
print(f"Trying letter {letter}...\nRemaining letters: {self.masked_sentence}")
每当我们创建新游戏实例时,__init__
部分就会运行,并接受三个参数,(self, chosen_words, hidden_words)
。 self
的使用引用了当前的 class 实例(或游戏),我们可以使用它来设置和检索 class 的属性,在这种情况下,以记住我们的单词和句子。
def __init__(self, chosen_words, hidden_words):
self.chosen_words = chosen_words
self.hidden_words = hidden_words
self.hidden_letters = list(set(''.join(hidden_words)))
self.masked_sentence = self.mask_words(chosen_words, hidden_words)
print(f"Game start: {self.masked_sentence}")
list(set(''.join(words)))
通过将它们连接成一个字符串来获取隐藏单词中的所有唯一字母,然后 using sets 将它们转换为唯一字母。我将其转换回列表以便于以后使用。
然后我们应用一个函数来屏蔽带有“_”的单词。
def mask_words(self, sentence, masks):
return ' '.join(['_'*len(w) if w in masks else w for w in sentence.split(' ')])
这遍历句子中的每个单词,如果它存在于隐藏单词中,则将其替换为单词长度的“_”。然后它加入备份。现在我们有了开始状态。
最后要做的是尝试一封信。我们通过定义一个方法(class 上的函数)def try_letter(self, letter=None):
来做到这一点。如果没有提供字母,我们会从我们之前定义的唯一缺失字母中随机选择一个。
我们使用 zip
一起检查原始句子和掩码句子中的每个字母,当原始字母是我们选择的字母时,我们替换掩码句子中的字母。
self.masked_sentence = ''.join(
[c if c==letter else m for m, c in zip(self.masked_sentence, self.chosen_words)]
)
然后从我们的隐藏字母列表中删除字母:
self.hidden_letters = [l for l in self.hidden_letters if l != letter]
最后,我们使用f-strings打印结果。
现在,我们可以玩游戏了!
chosen_word = "TO CRANK (STH) UP"
words = ['CRANK', 'UP']
game = VocabularyGame(chosen_word, words)
输出:Game start: TO _____ (STH) __
尝试一个字母 7 次 for i in range(7): game.try_letter()
输出:
Trying letter N...
Remaining letters: TO ___N_ (STH) __
Trying letter K...
Remaining letters: TO ___NK (STH) __
Trying letter R...
Remaining letters: TO _R_NK (STH) __
Trying letter P...
Remaining letters: TO _R_NK (STH) _P
Trying letter C...
Remaining letters: TO CR_NK (STH) _P
Trying letter U...
Remaining letters: TO CR_NK (STH) UP
Trying letter A...
Remaining letters: TO CRANK (STH) UP
我正在尝试编写一个词汇游戏。先声明一下,我是一个彻头彻尾的菜鸟程序员!
我正在使用正则表达式来隐藏一个我必须猜测的词。
以chosen_word为例:
'TO CRANK (STH) UP'
使用正则表达式,我设法隐藏了关键字,并且 hidden_word 如下:
TO _ _ _ _ _ (STH) _ _
使用 RegEx findall() 和 filter() 方法我得到了 hidden_letters:
['C', 'R', 'A', 'N', 'K', 'U', 'P']
我们现在的想法是从这个列表中随机选择一个字母来显示给用户:
chosen_letter = random.choice(hidden_letters)
n = hidden_letters.index(chosen_letter) + 1
现在所选字母的 n 漂亮地映射到 hidden_word 中相应的下划线。例如,如果游戏随机选择了字母 'R',那么 n 将是 '2',而在 hidden_word这个字母的位置在第2个下划线。
我现在卡在这个阶段了。我想用 chosen_letter[=59= 替换 nth 下划线 hidden_word ].我正在考虑使用 .replace() 方法或 RegEx re.sub() 方法,但我没有不知道如何开始。
有人可以给我提示吗?
非常感谢!!
我会以不同的方式处理这个问题:
每个时间点的状态定义为:
- 完整短语(待猜),
- 一组隐藏词,
- 到目前为止猜到的字母(或向用户透露)。
您可以使用这三个量定义一个 show()
函数:
def show(phrase, hidden_words, letters_guessed):
parts = [
''.join([
c if c in letters_guessed else '-' for c in w
]) if w in hidden_words else w
for w in phrase.split()
]
return ' '.join(parts)
有了这个,您可以编写测试,包括 doctests。这将使您的代码更易于记录、调试、测试和使用。
一些示例(可以作为文档测试包含在 show
的文档字符串中):
phrase = 'TO PIPE (STH) UP AND PIPE DOWN'
hidden_words = {'PIPE', 'UP'}
>>> show(phrase, hidden_words, {})
'TO ---- (STH) -- AND ---- DOWN'
>>> show(phrase, hidden_words, set('I'))
'TO -I-- (STH) -- AND -I-- DOWN'
>>> show(phrase, hidden_words, set('PI'))
'TO PIP- (STH) -P AND PIP- DOWN'
考虑到您是新手,我想把我的帽子扔进去,不使用正则表达式并尝试解释。也许只有在你开始之后才阅读这篇文章。您的问题标题可以这样回答:
def replace_nth_char(string, n, replacement):
n -= 1
l_string = list(string)
l_string[n] = replacement
return ''.join(l_string)
它将字符串转换为可以用索引替换的字母列表 n
,然后将其连接起来。
我还尝试了其余部分,向您展示了更多 python 选项。
在管理状态时,您可能需要考虑 using a class。它可以帮助您将所有功能和属性打包到一个 object 中,目的是玩您的词汇游戏。我建议调查一下。这是游戏的一个:
import random
class VocabularyGame():
def __init__(self, chosen_words, hidden_words):
self.chosen_words = chosen_words
self.hidden_words = hidden_words
self.hidden_letters = list(set(''.join(words)))
self.masked_sentence = self.mask_words(chosen_words, hidden_words)
print(f"Game start: {self.masked_sentence}")
def mask_words(self, sentence, masks):
return ' '.join(['_'*len(w) if w in masks else w for w in sentence.split(' ')])
def try_letter(self, letter=None):
if letter is None:
letter = random.choice(self.hidden_letters)
self.masked_sentence = ''.join(
[c if c== letter else m for m, c in zip(self.masked_sentence, self.chosen_words)]
)
self.hidden_letters = [l for l in self.hidden_letters if l != letter]
print(f"Trying letter {letter}...\nRemaining letters: {self.masked_sentence}")
每当我们创建新游戏实例时,__init__
部分就会运行,并接受三个参数,(self, chosen_words, hidden_words)
。 self
的使用引用了当前的 class 实例(或游戏),我们可以使用它来设置和检索 class 的属性,在这种情况下,以记住我们的单词和句子。
def __init__(self, chosen_words, hidden_words):
self.chosen_words = chosen_words
self.hidden_words = hidden_words
self.hidden_letters = list(set(''.join(hidden_words)))
self.masked_sentence = self.mask_words(chosen_words, hidden_words)
print(f"Game start: {self.masked_sentence}")
list(set(''.join(words)))
通过将它们连接成一个字符串来获取隐藏单词中的所有唯一字母,然后 using sets 将它们转换为唯一字母。我将其转换回列表以便于以后使用。
然后我们应用一个函数来屏蔽带有“_”的单词。
def mask_words(self, sentence, masks):
return ' '.join(['_'*len(w) if w in masks else w for w in sentence.split(' ')])
这遍历句子中的每个单词,如果它存在于隐藏单词中,则将其替换为单词长度的“_”。然后它加入备份。现在我们有了开始状态。
最后要做的是尝试一封信。我们通过定义一个方法(class 上的函数)def try_letter(self, letter=None):
来做到这一点。如果没有提供字母,我们会从我们之前定义的唯一缺失字母中随机选择一个。
我们使用 zip
一起检查原始句子和掩码句子中的每个字母,当原始字母是我们选择的字母时,我们替换掩码句子中的字母。
self.masked_sentence = ''.join(
[c if c==letter else m for m, c in zip(self.masked_sentence, self.chosen_words)]
)
然后从我们的隐藏字母列表中删除字母:
self.hidden_letters = [l for l in self.hidden_letters if l != letter]
最后,我们使用f-strings打印结果。 现在,我们可以玩游戏了!
chosen_word = "TO CRANK (STH) UP"
words = ['CRANK', 'UP']
game = VocabularyGame(chosen_word, words)
输出:Game start: TO _____ (STH) __
尝试一个字母 7 次 for i in range(7): game.try_letter()
输出:
Trying letter N...
Remaining letters: TO ___N_ (STH) __
Trying letter K...
Remaining letters: TO ___NK (STH) __
Trying letter R...
Remaining letters: TO _R_NK (STH) __
Trying letter P...
Remaining letters: TO _R_NK (STH) _P
Trying letter C...
Remaining letters: TO CR_NK (STH) _P
Trying letter U...
Remaining letters: TO CR_NK (STH) UP
Trying letter A...
Remaining letters: TO CRANK (STH) UP