Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用pythonmadlibs自动化枯燥的工作:替换匹配的正则表达式(丢失标点符号)会带来麻烦_Python_Regex - Fatal编程技术网

用pythonmadlibs自动化枯燥的工作:替换匹配的正则表达式(丢失标点符号)会带来麻烦

用pythonmadlibs自动化枯燥的工作:替换匹配的正则表达式(丢失标点符号)会带来麻烦,python,regex,Python,Regex,这是我的代码: import os, re def madLibs(): madLibsDirectory = 'madLibsFiles' os.chdir(madLibsDirectory) madLibsFile = 'panda.txt' madLibsFile = open(madLibsFile) file = madLibsFile.read() madLibsFile.close() wordRegex = re.com

这是我的代码:

import os, re

def madLibs():
    madLibsDirectory = 'madLibsFiles'
    os.chdir(madLibsDirectory)
    madLibsFile = 'panda.txt'
    madLibsFile = open(madLibsFile)
    file = madLibsFile.read()
    madLibsFile.close()

    wordRegex = re.compile(r"ADJECTIVE|VERB|ADVERB|NOUN")
    file = file.split() # split the madlib into a list with each word.
    for word in file:
    # check if word matches regex
        if wordRegex.match(word):
            foundWord = wordRegex.search(word) # create regex object on word
            newWord = input(f'Please Enter A {foundWord.group()}: ') # recieve word
            file[file.index(word)] = wordRegex.sub(newWord, foundWord.group(), 1)  
    file = ' '.join(file)
    print(file)

def main():
    madLibs()

if __name__ == '__main__':
    main()
问题行是
file[file.index(word)]=wordRegex.sub(newWord,foundWord.group(),1)

当我的程序运行在单词形容词、动词、副词和名词上时,它会提示用户输入一个单词,并用输入替换这个占位符。目前,该代码正确地替换了单词,但是,它没有保留标点符号。 例如,这里是panda.txt:

形容词panda依次指向名词和动词。邻近名词 没有受到这些事件的影响

当我用say“ate”替换动词时,它会这样做,但会删除句号:“…然后吃了附近的一个…”

我相信这个答案并不太复杂,但不幸的是,我的正则表达式知识还不是很好。
谢谢

您已正确识别出有问题的线路:

file[file.index(word)] = wordRegex.sub(newWord, foundWord.group(), 1)
这一行的问题是,您只替换了
foundWord.group()
的一部分,该部分仅包含匹配的单词,而不包含其周围出现的任何标点符号

一个简单的解决方法是完全删除
foundWord
,只需使用
word
作为替换文本即可。上面的一行将变成:

file[file.index(word)] = wordRegex.sub(newWord, word, 1)
那应该行!但是,您可以通过许多其他方式改进代码。例如,您不需要搜索
文件
中的
单词
来获取作业的正确索引,而应该使用
枚举
来获取每个
单词
的索引:

for i, word in enumerate(file):
    if ...
       ...
       file[i] = ...
或者你可以做一个更大的改变。
re.sub
函数(以及编译模式对象的等效方法)可以在一次传递中进行多个替换,并且它可以使用函数而不是字符串作为替换。每次模式在文本中匹配时,都将使用匹配对象调用该函数。那么,为什么不使用一个函数来提示用户输入替换词,并一次性替换所有关键字呢

def madLibs():
    madLibsDirectory = 'madLibsFiles'
    os.chdir(madLibsDirectory)
    filename = 'panda.txt'           # changed this variable name, to avoid duplication
    with open(filename) as file:     # a with statement will automatically close the file
        text = file.read()           # renamed this variable too

    wordRegex = re.compile(r"ADJECTIVE|VERB|ADVERB|NOUN")

    modified_text = wordRegex.sub(lambda match: input(f'Please Enter A {match.group()}: '),
                                  text)     # all the substitutions happen in this one call

    print(modified_text)
调用
wordRegex.sub
中的
lambda
相当于此命名函数:

def func(match):
    return input(f'Please Enter A {match.group()}: ')

我很确定这与标点符号消失的问题无关,但对于不同的事情重复使用变量名是一个非常糟糕的主意,就像对
madLibsFile
(既是文件名又是文件对象)和
file
(是文件中的文本,然后是单词列表)所做的那样。我建议使用不同的变量名,或者跳过中间步骤中不需要的变量,同时做几件事(例如,
madLibsFile=open('panda.txt')
,文件名不带变量)。我还建议使用
with
语句来确保文件被关闭。@Blckknght是的,我知道这是一种不好的做法。这段代码的文件打开部分相当混乱,是我之前做的一些奇怪实验的产物。在提交这个问题之前,我并没有费心去修正它,尽管我可能应该这样做。