簡體   English   中英

如何用“。”引爆句子但忽略雙引號中的“。”

[英]How to explode sentences with “。” but ignore the “。” in the double quotation marks

我正在編寫一個有關獲取中文文章摘要的程序。 首先,我必須用“。!!”這樣的符號來炸開每個句子。 在中文文章中,當提及他人的單詞時,他們會使用雙引號標記所指單詞,這些單詞可能包含“。”,但不應加以分解。 例如,以下句子:

他說:“今天天氣很好我很開心。”

它將分解為三個句子:

  1. 他說:“今天天氣很好
  2. 我很開心

結果是錯誤的,但是如何解決呢? 我嘗試使用正則表達式,但是我不擅長使用它,因此可以弄清楚。 PS:我用python3編寫此程序

我沒有拆分,而是使用re.findall匹配所有句子:

>>> s = '今天天氣很好。今天天氣很好。今天天氣很好。他說:“今天天氣很好。我很開心。”'
>>> re.findall('[^。“]+(?:。|“.*?”)', s)
['今天天氣很好。', '今天天氣很好。', '今天天氣很好。', '他說:“今天天氣很好。我很開心。”']

如果您也想接受其他字符作為分隔符,請嘗試以下操作:

>>> re.findall('[^。?!;~“]+(?:[。?!;~]|“.*?”)', s)

首先,我假設雙引號不能嵌套。 然后,不用一些復雜的正則表達式就可以很容易地做到這一點。 您只需在"分割,然后在標點符號上分割偶數部分。

>>> sentence = 'a: "b. c" and d. But e said: "f? g."'
>>> sentence.split('"')
['a: ', 'b. c', ' and d. But e said: ', 'f? g.', '']

您可以看到偶數部分是那些不在引號之間的部分。 我們將使用index % 2 == 1來選擇奇數部分。

result = []
part = []
for i, p in enumerate(sentence.split('"')):
    if i % 2 == 1:
        part.append(p)
    else:
        parts = p.split('.')
        if len(parts) == 1:
            part.append(p)
        else:
            first, *rest, last = parts
            part.append(first)
            result.append('"'.join(part))
            result.extend(rest)
            part = [last]

result.append('"'.join(part))

使用正則表達式:

import re

st=u'''\
今天天氣很好。今天天氣很好。bad? good! 今天天氣很好。他說:“今天天氣很好。我很開心。”
Sentence one. Sentence two! “Sentence three. Sentence four.” Sentence five?'''

pat=re.compile(r'(?:[^“。?!;~.]*?[?!。.;~])|(?:[^“。?!;~.]*?“[^”]*?”)')
print(pat.findall(st))

打印:

['今天天氣很好。', '今天天氣很好。', 'bad?', ' good!', ' 今天天氣很好。', 
 '他說:“今天天氣很好。我很開心。”', '\nSentence one.', ' Sentence two!', 
 ' “Sentence three. Sentence four.”', ' Sentence five?']

如果要分割效果(即不包括定界符),只需移動捕獲括號,然后打印匹配組即可:

pat=re.compile(r'([^“。?!;~.]*?)[?!。.;~]|([^“。?!;~.]*?“[^”]*?”)')
#  note the end paren:           ^
print([t[0] if t[0] else t[1] for t in pat.findall(st)])

打印:

['今天天氣很好', '今天天氣很好', 'bad', ' good', ' 今天天氣很好', 
 '他說:“今天天氣很好。我很開心。”', '\nSentence one', ' Sentence two', 
 ' “Sentence three. Sentence four.”', ' Sentence five']

或者,將re.split與相同的正則表達式一起使用,然后過濾True值:

print(list(filter(None, pat.split(st))))   

我認為您需要分兩個步驟進行操作:首先,找到雙引號內的點,然后對其進行“保護”(例如,用不太可能出現在雙引號中的$%$%$%$類的字符串替換它們)中文文本。)。 接下來,像以前一樣炸開琴弦。 最后,再次用點替換$%$%$%$

可能這將工作:

$str = '他說:“今天天氣很好。我很開心。”';
print_r( preg_split('/(?=(([^"]*"){2})*[^"]*$)。/u', $str, -1, PREG_SPLIT_NO_EMPTY) );

這可以確保匹配,只有當外面的雙引號。

OUTPUT:

Array
(
    [0] => 他說:“今天天氣很好
    [1] => 我很開心
    [2] => ”
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM