大小写文本取决于标点符号


根据

标点符号将文本更改为正确大小写的最有效方法是什么,并修复格式(空格等)?

the qUiCk BROWN fox:: jumped. over , the lazy    dog.

期望的结果:

The quick brown fox: jumped. Over, the lazy dog.

您标记了问题"正则表达式",但我不建议使用正则表达式来尝试解决此问题。 这最好使用简单的状态机来处理。

这是一个足以处理您的示例的简单状态机。 如果您在其他文本上尝试它,您可能会发现它无法处理的情况;我希望您会发现它的设计清晰,并且您可以毫不费力地修改它以适应您的目的。

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)

假设输入字符串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)

最新更新