我正在编写一个关于获取中文文章摘要的程序。首先,我必须用“。!?”之类的符号来爆炸每个句子。 在中文文章中,当引用其他词时,他们会使用双引号来标记所引用的词,这些词可能包含“。”但不应该分解。例如,以下句子:
他说:“今天天气很好我很开心”
它将分为三个句子:
结果是错误的,但如何解决呢? 我试过使用正则表达式,但我不擅长它,所以可以搞清楚。 PS:我用python3编写这个程序
答案 0 :(得分:2)
我使用re.findall
匹配所有句子而不是拆分:
>>> s = '今天天气很好。今天天气很好。今天天气很好。他说:“今天天气很好。我很开心。”'
>>> re.findall('[^。“]+(?:。|“.*?”)', s)
['今天天气很好。', '今天天气很好。', '今天天气很好。', '他说:“今天天气很好。我很开心。”']
如果您也想接受其他角色作为分隔符,请尝试以下方法:
>>> re.findall('[^。?!;~“]+(?:[。?!;~]|“.*?”)', s)
答案 1 :(得分:1)
首先,我假设双引号不能嵌套。然后在没有复杂的正则表达式的情况下很容易做到这一点。您只需在"
上拆分,然后在标点符号上拆分偶数部分。
>>> 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))
答案 2 :(得分:1)
使用正则表达式:
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))))
答案 3 :(得分:0)
我认为你需要分两步完成:首先,找到双引号内的点,并“保护”它们(例如,用$%$%$%$
之类的字符串替换它们,这些字符串不太可能出现在中文文本。接下来,像以前一样爆炸字符串。最后,再次用点替换$%$%$%$
。
答案 4 :(得分:0)
可能会有效:
$str = '他说:“今天天气很好。我很开心。”';
print_r( preg_split('/(?=(([^"]*"){2})*[^"]*$)。/u', $str, -1, PREG_SPLIT_NO_EMPTY) );
这可确保。
仅在外部双引号时匹配。
<强>输出:强>
Array
(
[0] => 他说:“今天天气很好
[1] => 我很开心
[2] => ”
)