2014-06-19 70 views
0
with open(searchfile) as f: 

pattern = "\.?(?P<sentence>.*?\(([A-Za-z0-9_]+)\).*?)\." 
for line in f: 
    match = re.search(pattern, line) 
    if match != None: 
     print match.group("sentence") 

我試圖提取包含在括號中的首字母縮寫的每一句話(主要是2-4字母在括號中全部大寫Python中提取包含括號每一句話

在:這裏是(ABC)例如(AVCD)這一個

輸出:這裏是一個(ABC)的例子,包括這個(AB)和(AVCD)這個。

回答

1

您可以使用此:

[^.]*?\([A-Z]{2,4}\)[^.]*\. 

但請注意,這是一種特別低效的方式,因爲模式以非常寬鬆的子模式開始。您可以矯正一點通過在開始時加入一種錨:

(?:(?<=.)|^)[^.]*?\([A-Z]{2,4}\)[^.]*\. 

不幸的是,即使有這樣的錨,正則表達式引擎必須檢查的大部分字符串的字符的兩個備選方案。

一個更好的辦法是找到字符串開頭的縮寫,直到這句話,點結束,然後提取使用結束每個結果的偏移子:

#!/usr/bin/python 

import re 

txt = 'Here is an (ABC) example. Do not include this sentence. Include this (AB) one. And (AVCD) this one.' 

pattern = re.compile(r'([!.?])(?=\s)|\([A-Z]{2,4}\)[^.]*(?:\.|$)') 
offset = 0 
result = '' 
for m in pattern.finditer(txt): 
    if (m.group(1)==None): 
     result += txt[offset:m.end()] 
    offset = m.end() 

print result  

注意:你可以確定一個點代表句子的結尾,它可以是別的。

+0

,將工作,+1 :) – zx81

+0

我怎麼會做這個,而是從文本文件中讀取數據,而不是一個字符串?我一次循環一行的實現只返回第一行。 – mrobillard

+0

@mrobillard:你可以輕鬆做到。所有你需要的是在for循環之後(外部)存儲一個變量,比如'subeol',結束行(從'offset'到end)。在for循環中,'result'現在是:'result + = subeol + txt [offset:m.end()]',並且在if語句後,必須將'subeol'初始化爲一個空字符串。你只需要把所有的東西都放在線路循環中。 –

0

一點更高效的模式

([^.(]++\([^.)]++\)[^.)]++\.) 

Demo