我不會建議使用您匹配的單詞不同的定界符兩邊
它更容易(%
並在你的例子&
。)在標記的單詞的任一側使用相同的分隔符並使用Python的列表分片。
以下解決方案使用[::n]
語法獲取列表中的每個n
個元素。
a[::2]
得到偶數編號的元素,a[1::2]
得到奇數。
>>> fox = "the|quick|brown|fox|jumpsoverthelazydog"
因爲他們兩邊|
字符,'quick'
和'fox'
是奇數的元素,當你劈在|
字符串:
>>> splitfox = fox.split('|')
>>> splitfox
['the', 'quick', 'brown', 'fox', 'jumpsoverthelazydog']
>>> splitfox[1::2]
['quick', 'fox']
,其餘均爲偶數:
>>> splitfox[::2]
['the', 'brown', 'jumpsoverthelazydog']
因此,通過將|
字符中的已知單詞括起來,分割並掃描even-nu複雜的元素,您只能搜索那些尚未匹配的文本部分。這意味着你在已經匹配的單詞中不匹配。
from itertools import chain
def flatten(list_of_lists):
return chain.from_iterable(list_of_lists)
def parse(source_text, words):
words.sort(key=len, reverse=True)
texts = [source_text, ''] # even number of elements helps zip function
for word in words:
new_matches_and_text = []
for text in texts[::2]:
new_matches_and_text.append(text.replace(word, f"|{word}|"))
previously_matched = texts[1::2]
# merge new matches back in
merged = '|'.join(flatten(zip(new_matches_and_text, previously_matched)))
texts = merged.split('|')
# remove blank words (matches at start or end of a string)
texts = [text for text in texts if text]
return ' '.join(texts)
>>> parse('acatisananimal', ['cat', 'is', 'a', 'an', 'animal'])
'a cat is an animal'
>>> parse('atigerisanenormousscaryandbeautifulanimal', ['tiger', 'is', 'an', 'and', 'animal'])
'a tiger is an enormousscary and beautiful animal'
的merge
代碼使用zip
和flatten
功能拼接的新比賽和老一起匹配。它基本上是通過將列表中的偶數和奇數元素進行配對來實現的,然後將結果「拼合」成一個長列表,爲下一個單詞做好準備。
該方法在文本中留下無法識別的單詞。
'beautiful'
和'a'
處理得好,因爲他們對自己的(即靠近識別的單詞。)
'enormous'
和'scary'
不是已知的,因爲他們是彼此相鄰,他們離開粘在一起。
下面是如何列出未知的話:
>>> known_words = ['cat', 'is', 'an', 'animal']
>>> sentence = parse('anayeayeisananimal', known_words)
>>> [word for word in sentence.split(' ') if word not in known_words]
['ayeaye']
我很好奇:這是一個生物信息學項目?
你現在的輸出是什麼? –
@ t.m.adam嗯,我知道。但是,當我在評論的上下文中使用定義時,我問的是「最終」初始化_任何地方_。但是,是的,你完全正確。 –
[我的解決方案](http://stackoverflow.com/a/43366440/5811078)也適用於這種情況。 – zipa