根据标点符号和修复格式(空白等),将文本更改为正确的最有效方法是什么?
the qUiCk BROWN fox:: jumped. over , the lazy dog.
期望的结果:
The quick brown fox: jumped. Over, the lazy dog.
答案 0 :(得分:2)
您标记了您的问题“正则表达式”但我不建议使用正则表达式来尝试解决此问题。最好使用简单的状态机来处理。
这是一个足以处理你的例子的简单状态机。如果你在其他文本上尝试它,你可能会发现它无法处理的情况;我希望你会发现它的设计清晰,你可以毫不费力地修改它以适应你的目的。
import string
s = "the qUiCk BROWN fox:: jumped. over , the lazy dog."
s_correct = "The quick brown fox: jumped. Over, the lazy dog."
def chars_from_lines(lines):
for line in lines:
for ch in line:
yield ch
start, in_sentence, saw_space = range(3)
punct = set(string.punctuation)
punct_non_repeat = punct - set(['.', '-'])
end_sentence_chars = set(['.', '!', '?'])
def edit_sentences(seq):
state = start
ch_punct_last = None
for ch in seq:
ch = ch.lower()
if ch == ch_punct_last:
# Don't pass repeated punctuation.
continue
elif ch in punct_non_repeat:
ch_punct_last = ch
else:
# Not punctuation to worry about, so forget the last.
ch_punct_last = None
if state == start and ch.isspace():
continue
elif state == start:
state = in_sentence
yield ch.upper()
elif state == in_sentence and ch in end_sentence_chars:
state = start
yield ch
yield ' '
elif state == in_sentence and not ch.isspace():
yield ch
elif state == in_sentence and ch.isspace():
state = saw_space
continue
elif state == saw_space and ch.isspace():
# stay in state saw_space
continue
elif state == saw_space and ch in punct:
# stay in state saw_space
yield ch
elif state == saw_space and ch.isalnum():
state = in_sentence
yield ' '
yield ch
#with open("input.txt") as f:
# s_result = ''.join(ch for ch in edit_sentences(chars_from_lines(f)))
s_result = ''.join(ch for ch in edit_sentences(s))
print(s_result)
print(s_correct)
答案 1 :(得分:1)
假设line
是输入字符串。以下应该做一些非常接近你想要的事情。请注意,换行符(和其他空格)将转换为单个空格。
import string # used to check if a character is a letter
#assume we start with a letter and not, for instance, a quotation mark
assert line[0] in string.letters
line = line.capitalize()
duplPunct = [] #list of indices of duplicate punctuation
prev = line[0]
for i in range(len(line))[1:]:
if line[i] == prev and prev not in string.letters:
duplPunct.append(i)
prev = line[i]
while len(duplPunct):
i = duplPunct.pop() #returns last index needing deletion
line = line[:i]+line[i+1:]
words = line.split() #removes all whitespace
floatingchar = [] #list of indices of words containing only a single invalid character
for i in range(len(words))[1:]:
word = words[i]
if len(word) == 1 and word not in 'ai':
#assume single-character 'words' should be part of previous word
floatingchar.append(i)
while len(floatingchar):
i = floatingchar.pop()
words[i-1] = words[i-1]+words[i]
del words[i]
needCaps = [] #list of indices of words requiring capitalization
for i in range(len(words))[:-1]:
if words[i][-1] in '.!?':
needCaps.append(i+1)
while len(needCaps):
i = needCaps.pop()
words[i] = words[i].capitalize()
line = ' '.join(words)