2015-01-20 46 views
2

我想解析字符串的方式來分離出所有的單詞組件,甚至那些已經收縮。例如,「不應該」的標記將是[「應該」,「不」)。Python的正則表達式:令牌化英文收縮

的NLTK模塊似乎並沒有達到任務然而由於:

「我wouldn't've做到這一點。」

爲標記化:

[ '我', 「不會」, 「've」 的 '完成', '那個','']

哪裏「would''''ve」的理想標記是:['會','不是',''ve']

在檢查了常見的英語收縮之後,我試着寫一個正則表達式來完成這個工作但我很難弄清楚如何匹配「've」只有一次。例如,下列標記都可以終止收縮:

不, 'VE,' d'LL,年代,「M '再次

但令牌「' VE」,也可以按照其他的收縮,如:

'D'VE,n't've,和(想像)' ll've

此刻,我想纏鬥這個正則表達式:

\ b [a-zA-Z] +(?:('d |'ll | not)('ve)?)|('s |'m |'re |'ve) \ b

然而,這種模式也匹配形成嚴重:

「wouldn't've've」

看來問題是,第三撇號資格作爲一個字的邊界,以便最後的''ve'標記匹配整個正則表達式。

我一直無法想出一種方法來區分單詞邊界與撇號,如果不這樣做,我願意提供替代策略的建議。

此外,我很好奇,如果有任何方法在字符類中包含字邊界特殊字符。根據Python文檔,\ b在一個字符類中匹配一個退格,並且似乎沒有辦法解決這個問題。

編輯:

下面是輸出:

>>>pattern = re.compile(r"\b[a-zA-Z]+(?:('d|'ll|n't)('ve)?)|('s|'m|'re|'ve)\b") 
>>>matches = pattern.findall("She'll wish she hadn't've done that.") 
>>>print matches 
[("'ll", '', ''), ("n't", "'ve", ''), ('', '', "'ve")] 

我想不通的第三場比賽。特別是,我剛剛意識到,如果第三個撇號匹配前導\ b,那麼我不知道匹配字符類[a-zA-Z] +的是什麼。

回答

2
(?<!['"\w])(['"])?([a-zA-Z]+(?:('d|'ll|n't)('ve)?|('s|'m|'re|'ve)))(?(1)\1|(?!\1))(?!['"\w]) 

編輯:\ 2是匹配,\ 3是第一組,\ 4是第二組和\ 5第三。

+0

謝謝。但是,這讓人感到困惑:「她希望她沒有做到這一點。」並在其他時間返回大量無關組。 – Schemer 2015-01-20 21:10:27

+0

你能否提供一些例子,以便我們知道要測試什麼?我編輯了我的代碼,以便與我的一些例子和你的代碼一起工作。演示:https://regex101.com/r/iV4cX6/1 – AMDcze 2015-01-20 21:41:52

+0

你的前瞻/後面的斷言指出我:'\ b(?<!')[a-zA-Z] +('s |'m |''|''|'| d | not)('ve)?)(?!')\ b'解決了目前的任務。撇號被匹配爲詞邊界,但在開始時和結束時都是如此。另外,在我注意到不匹配的括號之前,我可能已經死亡並且下地獄了。謝謝! – Schemer 2015-01-20 21:49:55

1

您可以使用下面的完整的正則表達式:

import re 
patterns_list = [r'\s',r'(n\'t)',r'\'m',r'(\'ll)',r'(\'ve)',r'(\'s)',r'(\'re)',r'(\'d)'] 
pattern=re.compile('|'.join(patterns_list)) 
s="I wouldn't've done that." 

print [i for i in pattern.split(s) if i] 

結果:

['I', 'would', "n't", "'ve", 'done', 'that.'] 
+1

謝謝。但是,這也與我不願意忽略的「不會」的「不可能」形成匹配。 – Schemer 2015-01-20 21:07:09

1

您可以使用此正則表達式來標記文本:

(?:(?!.')\w)+|\w?'\w+|[^\s\w] 

用法:

>>> re.findall(r"(?:(?!.')\w)+|\w?'\w+|[^\s\w]", "I wouldn't've done that.") 
['I', 'would', "n't", "'ve", 'done', 'that', '.'] 
+1

謝謝。但是這種模式並不排除組成不好的「不會」。 – Schemer 2015-01-20 20:51:01

1
>>> import nltk 
>>> nltk.word_tokenize("I wouldn't've done that.") 
['I', "wouldn't", "'ve", 'done', 'that', '.'] 

這樣:

>>> from itertools import chain 
>>> [nltk.word_tokenize(i) for i in nltk.word_tokenize("I wouldn't've done that.")] 
[['I'], ['would', "n't"], ["'ve"], ['done'], ['that'], ['.']] 
>>> list(chain(*[nltk.word_tokenize(i) for i in nltk.word_tokenize("I wouldn't've done that.")])) 
['I', 'would', "n't", "'ve", 'done', 'that', '.'] 
0

這裏一個簡單的

text = ' ' + text.lower() + ' ' 
text = text.replace(" won't ", ' will not ').replace("n't ", ' not ') \ 
    .replace("'s ", ' is ').replace("'m ", ' am ') \ 
    .replace("'ll ", ' will ').replace("'d ", ' would ') \ 
    .replace("'re ", ' are ').replace("'ve ", ' have ')