Created
July 25, 2016 18:07
-
-
Save quynguyen3490/04cc1178efd0ae06bff7b59627626f9b to your computer and use it in GitHub Desktop.
Split Vietnamese Sentences
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
""" | |
Split sentences | |
Author: Quy Nguyen | |
Tested under Python 2.7 | |
""" | |
import io | |
import re | |
#tất cả ký tự viết hoa tiếng Việt | |
UPPERUNICODE = [u'\u00C1',u'\u00C0',u'\u00C2',u'\u0102',u'\u00C3',u'\u1EA4',u'\u1EA6',u'\u1EAE',u'\u1EB0',u'\u1EAA',u'\u1EB4',u'\u1EA2',u'\u1EA8',u'\u1EB2',u'\u1EA0',u'\u1EAC',u'\u1EB6',u'\u0110',u'\u00C9',u'\u00C8',u'\u00CA',u'\u1EBC',u'\u1EBE',u'\u1EC0',u'\u1EC4',u'\u1EBA',u'\u1EC2',u'\u1EB8',u'\u1EC6',u'\u00CD',u'\u00CC',u'\u0128',u'\u1EC8',u'\u1ECA',u'\u00D3',u'\u00D2',u'\u00D4',u'\u00D5',u'\u1ED0',u'\u1ED2',u'\u1ED6',u'\u1ECE',u'\u01A0',u'\u1ED4',u'\u1ECC',u'\u1EDA',u'\u1EDC',u'\u1EE0',u'\u1ED8',u'\u1EDE',u'\u1EE2',u'\u00DA',u'\u00D9',u'\u0168',u'\u1EE6',u'\u01AF',u'\u1EE4',u'\u1EE8',u'\u1EEA',u'\u1EEE',u'\u1EEC',u'\u1EF0',u'\u00DD',u'\u1EF2',u'\u1EF8',u'\u1EF6',u'\u1EF4'] | |
#tất cả ký tự viết thường tiếng Việt | |
LOWERUNICODE = [u'\u00E1',u'\u00E0',u'\u00E2',u'\u0103',u'\u00E3',u'\u1EA5',u'\u1EA7',u'\u1EAF',u'\u1EB1',u'\u1EAB',u'\u1EB5',u'\u1EA3',u'\u1EA9',u'\u1EB3',u'\u1EA1',u'\u1EAD',u'\u1EB7',u'\u0111',u'\u00E9',u'\u00E8',u'\u00EA',u'\u1EBD',u'\u1EBF',u'\u1EC1',u'\u1EC5',u'\u1EBB',u'\u1EC3',u'\u1EB9',u'\u1EC7',u'\u00ED',u'\u00EC',u'\u0129',u'\u1EC9',u'\u1ECB',u'\u00F3',u'\u00F2',u'\u00F4',u'\u00F5',u'\u1ED1',u'\u1ED3',u'\u1ED7',u'\u1ECF',u'\u01A1',u'\u1ED5',u'\u1ECD',u'\u1EDB',u'\u1EDD',u'\u1EE1',u'\u1ED9',u'\u1EDF',u'\u1EE3',u'\u00FA',u'\u00F9',u'\u0169',u'\u1EE7',u'\u01B0',u'\u1EE5',u'\u1EE9',u'\u1EEB',u'\u1EEF',u'\u1EED',u'\u1EF1',u'\u00FD',u'\u1EF3',u'\u1EF9',u'\u1EF7',u'\u1EF5'] | |
#ký tự được xem là kết thúc câu | |
BOUDARYSYMBOL = ['.','!','?',u'\u2026',u'…'] | |
#ký tự trắng | |
WHITE_SPACE = ' ' | |
#ký tự dấu ba chấm | |
ELLIPSIS = u'\u2026' | |
#kiểm tra ký tự kết thúc câu | |
def isBoundarySymbol(char): | |
for c in BOUDARYSYMBOL: | |
if c == char: return 1 | |
return 0 | |
#kiểm tra ký tự viết hoa tiếng Việt | |
def isUniUpper(char): | |
for c in UPPERUNICODE: | |
if c == char: return 1 | |
return 0 | |
#kiếm tra ký tự viết thường tiếng Việt | |
def isUniLower(char): | |
for c in LOWERUNICODE: | |
if c == char: return 1 | |
return 0 | |
#kiểm tra có phải kết thúc 1 câu hay ko | |
def isBoudary(i,text): | |
#kiểm tra hết text | |
if i == len(text)-1: return 1 | |
#nếu i+1 là ký tự trắng thì trả về 1 | |
if re.match(ur'\s',text[i+1]): return 1 | |
#nếu i-1 là số và i+1 là số thì trả về 0 | |
if re.match(ur'[0-9]',text[i-1]) and re.match(ur'[0-9]',text[i+1]): return 0 | |
#nếu i-1 là số và i+1 không phải là số thì trả về 1 | |
if re.match(ur'[0-9]',text[i-1]) and re.match(ur'[^0-9]',text[i+1]): return 1 | |
#nếu i-1 là ký tự thường và i+1 là ký tự hoa thì trả về 1 | |
if (re.match(ur'[a-z\)\"\”]',text[i-1]) or isUniLower(text[i-1])) and (re.match(ur'[A-Z\(\"\“)]',text[i+1]) or isUniUpper(text[i+1])): return 1 | |
#nếu i-1 là ký tự hoa và i+1 là ký tự hoa thì trả về 0 | |
if (re.match(ur'[A-Z]',text[i-1]) or isUniUpper(text[i-1])) and (re.match(ur'[A-Z]',text[i+1]) or isUniUpper(text[i+1])): return 0 | |
return 0 | |
#cắt câu | |
def SplitSentence(text): | |
text = text.strip() | |
text = text.replace('\t', u'. ') | |
text = text.replace('\v', u'. ') | |
text = text.replace('\r', u'. ') | |
text = text.replace('\r\n', u'. ') | |
text = text.replace(u'...', u'. ') | |
text = text.replace(u'..', u'. ') | |
text = text.replace(u'…', u'. ') | |
sents = [] | |
#ký tự i bắt đầu =0 | |
i = 0 | |
#ký tự bắt đầu câu =0 | |
begin = 0 | |
#lặp từng ký tự trong text | |
while i < len(text): | |
for sym in BOUDARYSYMBOL: | |
#nếu gặp ký tự kết thúc | |
if sym == text[i]: | |
#kiểm tra đó có phải vị trí kết thúc câu hay ko | |
if isBoudary(i,text): | |
#nếu là kết thúc câu thì cắt câu đó ra và tiếp tục | |
sents.append(text[begin:i].strip()) | |
begin=i+1 | |
i+=1 | |
return sents | |
#hàm chạy trên cùng | |
if __name__ == "__main__": | |
import sys, io, codecs | |
if len(sys.argv) == 1: | |
print('Usage: python sent_proc.py <utf8_text_file.txt>') | |
sys.exit(0) | |
try: | |
with codecs.open(sys.argv[1], 'r', 'utf-8') as fTxt: text = fTxt.read() | |
except IOError: | |
sys.exit('Failed to load text file ' + sys.argv[1] + '. Exit now!') | |
sents = SplitSentence(text) | |
with codecs.open('sent_proc_output.txt','w','utf-8') as fb: | |
for s in sents: | |
fb.write(s+u'\n') | |
print('Output file will save same folder with name "sent_proc_output.txt"') | |
sys.exit(0) |
Dear Anh,
Anh cho em hỏi đến thời điểm hiện tại anh có update chủ đề tách câu này không ạ.
Em chạy thử nghiệm source code của anh với case: "Mr. Hà Lê, Ph.D của CL đến từ học viện Karlsruhe"
Kết quả trả về 3 sentences:Mr
Hà Lê
Ph
Các từ còn lại sau Ph bị mất.
đó là trường hợp đặc biệt r đơn giản thì mình thêm điều kiện : if i == len(text)-2 : in [Mr,Ms,Dr,...] vào trước hàm kiểm tra kết thúc câu là dc
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Dear Anh,
Anh cho em hỏi đến thời điểm hiện tại anh có update chủ đề tách câu này không ạ.
Em chạy thử nghiệm source code của anh với case: "Mr. Hà Lê, Ph.D của CL đến từ học viện Karlsruhe"
Kết quả trả về 3 sentences:
Mr
Hà Lê
Ph
Các từ còn lại sau Ph bị mất.