2015-10-02 83 views
1

我需要知道文本中某個單詞的所有位置 - 字符串中的子串。到目前爲止的解決方案是使用正則表達式,但我不確定是否沒有更好的,可能內置標準庫策略。有任何想法嗎?子串在字符串中的位置

import re 

text = "The quick brown fox jumps over the lazy dog. fox. Redfox." 
links = {'fox': [], 'dog': []} 
re_capture = u"(^|[^\w\-/])(%s)([^\w\-/]|$)" % "|".join(links.keys()) 

iterator = re.finditer(re_capture, text) 

if iterator: 
    for match in iterator: 

     # fix position by context 
     # (' ', 'fox', ' ') 
     m_groups = match.groups() 
     start, end = match.span() 
     start = start + len(m_groups[0]) 
     end = end - len(m_groups[2]) 

     key = m_groups[1] 
     links[key].append((start, end)) 

print links 

{ '狐狸':[(16,19),(45,48)], '狗':[(40,43)]}

編輯:部分的話不允許匹配 - 見狐狸Redfox不在鏈接。

謝謝。

+0

重複http://stackoverflow.com/questions/3437059/does-python-have-a-字符串包含子字符串方法 –

+0

@RNar這不是一個重複的原因OP尋找*所有*發生。 – alfasin

+0

爲什麼你的正則表達式如此複雜?也是重新是標準庫的一部分吧 –

回答

1

如果要匹配實際的話,你的字符串包含ASCII:

text = "fox The quick brown fox jumps over the fox! lazy dog. fox!." 
links = {'fox': [], 'dog': []} 

from string import punctuation 
def yield_words(s,d): 
    i = 0 
    for ele in s.split(" "): 
     tot = len(ele) + 1 
     ele = ele.rstrip(punctuation) 
     ln = len(ele) 
     if ele in d: 
      d[ele].append((i, ln + i)) 
     i += tot 
    return d 

這不像找到解決將不匹配部分單詞和IT在O(n)時間:

In [2]: text = "The quick brown fox jumps over the lazy dog. fox. Redfox." 

In [3]: links = {'fox': [], 'dog': []} 

In [4]: yield_words(text,links) 
Out[4]: {'dog': [(40, 43)], 'fox': [(16, 19), (45, 48)]} 

這可能是一個情況下一個reg EX是一個很好的方法,它可以只是簡單得多:

def reg_iter(s,d): 
    r = re.compile("|".join([r"\b{}\b".format(w) for w in d])) 
    for match in r.finditer(s): 
     links[match.group()].append((match.start(),match.end())) 
    return d 

輸出:

In [6]: links = {'fox': [], 'dog': []} 

In [7]: text = "The quick brown fox jumps over the lazy dog. fox. Redfox." 

In [8]: reg_iter(text, links) 
Out[8]: {'dog': [(40, 43)], 'fox': [(16, 19), (45, 48)]} 
+0

到目前爲止,您的答案是我最喜歡的 - reg_iter - 更短,速度更快,它解決了我的問題中甚至沒有提到的邊緣情況:當我使用德語元音變形處理大量文本時,您的代碼剛剛工作也是這樣。 – rebeling

+0

評分和解釋將很快添加 - 可能會有別的東西放在桌子上,我們都沒有想到過,謝謝你的回答;) – rebeling

+0

@rebeling,不用擔心,很高興它有幫助 –

3

不是Python的,沒有正則表達式:

text = "The quick brown fox jumps over the lazy dog. fox." 
links = {'fox': [], 'dog': []} 

for key in links: 
    pos = 0 
    while(True): 
     pos = text.find(key, pos) 
     if pos < 0: 
      break 
     links[key].append((pos, pos + len(key))) 
     pos = pos + 1 
print(links) 
+1

我喜歡你的代碼,你可以編輯將你的整個代碼縮進四個空格嗎?此外,如果您要將'鏈接鏈接'改爲'鏈接鏈接'來匹配正常的字典處理,那就太棒了。 –

+0

部分文字不允許匹配 - 請參閱Redfox。 – rebeling

+0

你的代碼在我的情況下不起作用 - 許多條件適用於比賽。謝謝你的努力。 – rebeling

相關問題