我在写拼写检查程序,如何替换字符串中的ch?
我哪里做错了/我可以怎么做?
import sys
import string
def remove(file):
punctuation = string.punctuation
for ch in file:
if len(ch) > 1:
print('error - ch is larger than 1 --| {0} |--'.format(ch))
if ch in punctuation:
ch = ' '
return ch
else:
return ch
ref = (open("ref.txt","r"))
test_file = (open("test.txt", "r"))
dictionary = ref.read().split()
file = test_file.read().lower()
file = remove(file)
print(file)
这是在Python 3.1.2版本中。
3 个回答
看看re(正则表达式)模块。它里面有一个叫“sub”的功能,可以用来替换那些符合正则表达式的字符串。
在Python中,字符串是不可变的,也就是说你不能直接修改它们,所以如果你想改变字符串,就得创建一个新的字符串。
有几种方法可以做到这一点:
一种方法是使用列表推导式,这样可以检查每个字符,并只返回那些不是标点符号的字符。
def remove(file):
return ''.join(ch for ch in file if ch not in string.punctuation)
你也可以调用一些函数来测试字符,或者转换字符,这样可能会抛出“奇怪字符”的异常,或者执行其他功能:
def remove(file):
return ''.join(TranslateCh(ch) for ch in file if CheckCh(ch))
另外一个选择是使用string
模块,它提供了replace
或translate
功能。使用translate
可以更高效地处理这个问题,比起构建一个列表要好很多,具体可以参考Alex的回答。
或者……你可以通过for
循环收集一个列表,最后再把它们连接起来,但这样做有点“不够Python风格”。
在这段代码中……:
for ch in file:
if len(ch) > 1:
这个奇怪命名的 file
(除了违反了不使用自己的名字来覆盖内置名称的最佳实践)其实并不是一个文件,而是一个字符串——在Python 3中,这意味着它是unicode字符串。不过这并不影响循环返回的是单个字符(在Python 3中是unicode字符,而不是字节),所以 len(ch) == 1
是Python语言规则下绝对成立的。我不太确定你想通过这个测试达到什么目的(是想排除某些unicode字符吗?),但无论你认为自己在实现什么,我可以保证你并没有做到,应该重新编写那部分代码。
除此之外,你是立即返回——因此也就是退出了这个函数——这样一来,你只返回了一个字符(要么是文件中的第一个字符,要么如果第一个字符是标点符号,则返回一个空格)。
我在另一个回答中看到的建议使用 translate
方法是正确的,但那个回答使用了错误版本的 translate
(适用于字节字符串,而不是你在Python 3中需要的unicode字符串)。正确的unicode版本更简单,可以把你的整个函数简化为仅仅两条语句:
trans = dict.fromkeys(map(ord, string.punctuation), ' ')
return file.translate(trans)