2014-02-09 35 views
1

我想創建一個Python函數,可以將文本分割成句子。我想分期(。),問號(?)或感嘆號(!)。然而,這個標準有一些例外,我認爲它是正則表達式。 pattern1到5用於排除,pattern6用於匹配。我想找到所有與pattern6匹配的模式,但不能匹配任何模式1到5.是否可以在Python正則表達式中這樣做?還是我沒有朝着正確的方向思考?結合多個正則表達式1匹配和排除

pattern1 = '\. [a-z]' 
pattern2 = '\.\d' 
pattern2 = '(Mr|Mrs|Dr|Jr)\. [A-Z]' 
pattern4 = '[a-zA-Z]\.[a-zA-Z]' 
pattern5 = '\.(\.|,)' 

pattern6 = '\.[\s][A-Z]' 

當我將模式1到5與|在pythex中,

pattern1|pattern2|patter3|pattern4|pattern5 

我可以找到所有我想要排除的場景。然後我試着用排除他們^與pattern6相結合,得到一個非常醜陋的正則表達式:

(^((\. [a-z])|(\.\d)|((Mr|Dr|Jr|Mrs)\.[A-Z])|([A-Za-z]\.[A-Za-z])|(\.(\.|,))))|(\.[\s][A-Z]) 

這裏是

(^((pattern1)|(pattern2)|(pattern3)|(pattern4)|(pattern5)))|(pattern6) 

這是工作在一定程度上,但未能與模式名稱取代了簡單的模式對於「史密斯先生」等案件,我剛開始學習正則表達式,所以請原諒我的髒代碼。希望能提供編寫良好可讀正則表達式的指南。

添加樣本輸入:

史密斯先生買cheapsite.com爲150萬美元,即他付出了很多 它。他介意嗎?小亞當瓊斯認爲他沒有。在任何情況下, 這是不正確的......好吧,以.9的概率它不是。

正確的輸出應該是句

不正確的輸出是在任何分裂的列表。不標記句子結尾

+0

樣本輸入,樣本失敗輸出,樣本正確輸出? – roippi

回答

1

您可能會考慮僅在模式6上進行拆分,然後使用周邊查找排除模式3和5,因爲儘管強制執行模式6,模式3仍然可以匹配(模式3具有空格+大寫在時段和模式5之後不得不忽略連續的時段)。

這是具有正先行圖案6:

\.(?=\s[A-Z]) 

要排除圖案3,添加負lookbehinds:

(?<!Mr|Dr|Jr)(?<!Mrs)\.(?=\s[A-Z]) 

我使用單獨的負回顧後因爲python的lookbehinds不能是可變寬度的。所有的Mr,DrJr都是2個字符,但是Mrs 3。

您可以更短,去年的正則表達式:

(?<![MDJ]r)(?<!Mrs)\.(?=\s[A-Z]) 

要排除拍打5現在,另一個負回顧後:

(?<![MDJ]r)(?<!Mrs)(?<!\.)\.(?=\s[A-Z]) 

在此之後,它不會分裂的連續週期。

現在,你已經有了一段時間下來,你可以很容易地使用一個字符類拆就!?

(?<![MDJ]r)(?<!Mrs)(?<!\.)[.?!](?=\s[A-Z]) 

順便說一句,在^是不完全用於否定正則表達式。 [^ ... ]取而代之的是用於否定,當你不關心字符的順序。例如,[^aeiou]將以任何順序匹配除字母aeiou之外的任何一個字符。另外,正則表達式中的大多數元字符在字符類中失去了它們的含義(這是方括號中的東西)。例如,()將成爲[]之間的文字字符,不能再用於分組。

^在字符類以外用來表示行的開始。

+0

感謝您的詳細解釋。感覺愚蠢,我用^否定,雖然我之前讀過......似乎我需要睡一覺。然後閱讀關於前瞻和後視。這個概念對我來說是新的。 –

+0

@ user3097807不用擔心,當你開始學習正則表達式時,有太多的符號需要注意,我知道要區分它們並不容易。慢慢來。我會建議先獲得基礎知識。 lookaheads和lookbehinds是更高級的語法。嘗試先理解字符類,捕獲和非捕獲組,錨定,基本量詞和反向引用。然後轉向lookaround(lookahead和lookbehind)。我發現[這個網站](http://www.regular-expressions.info/)非常適合學習正則表達式。 – Jerry

+0

非常感謝傑裏:-)我希望我可以投你的答案,但我沒有那麼多的聲譽...... –

0

在我的知識有沒有排除模式^是不包括設置爲[^ AB]一個字符的字符外就意味着該字符串的開頭是不是你想要

你必須做兩步匹配

pattern1 = r'\. [a-z]' 
pattern2 = r'\.\d' 
pattern2 = r'(Mr|Mrs|Dr|Jr)\. [A-Z]' 
pattern4 = r'[a-zA-Z]\.[a-zA-Z]' 
pattern5 = r'\.(\.|,)' 

pattern6 = r'\.[\s][A-Z]' 

if re.match(pattern6): 
    if not re.match("("+pattern1+"|"+pattern2+"|"+pattern3+"|"+pattern4+"|"+pattern5+")"): 
      do_whatever_you_want()