2013-11-14 143 views
1

我正在研究能够在字符串中进行特定模式的近似匹配的脚本,仅报告这些模式(它们可能会重叠)发起的位置。近似匹配的位置

到目前为止,我获得可以报告的精确匹配的位置的剧本,但没有成功近似的:

import re 
stn = 'KLHLHLHKPLHLHLPHHKLHKLPKPH' 
pat = 'KLH' 
matches = re.finditer(r'(?=(%s))' % re.escape(pat), stn) 
finalmatch= [m.start() for m in matches] 
pos = ' '.join(str(v) for v in finalmatch) 
print pos 

结果在这种情况下是:但如果脚本报告也大致匹配?即如果最大允许误差(容差或阈值)是1(在查询模式的任何位置),那么HLH,PLH,KLP,KPH的初始位置如何被报告?

我已经试图包括距离度量像Levenshtein或SequenceMatcher,但没有成功。

在此先感谢您的帮助。

回答

0

只要改变图案:

import re 
from itertools import chain 
stn = 'KLHLHLHKPLHLHLPHHKLHKLPKPH' 
pats = ['KLH', 'KL, 'LH, 'K', 'L', 'H'] 
matches = [] 
for pat in pats: 
    matches = chain(matches, (re.finditer(r'(?=(%s))' % re.escape(pat), stn)) 
finalmatch= [m.start() for m in matches] 
pos = ' '.join(str(v) for v in finalmatch) 
print pos 
+0

我理解的想法,但脚本挑衅,因为不完整的子像“LH(无效语法)的错误。我不知道如何解决这个问题,而不会像使用矩阵或类似的情况那样使问题复杂化。 –

+0

我刚刚意识到您正在使用'finditer()',这意味着您需要使用'chain()'而不是列表扩展名。也许这可以帮助?如果不是,你可以提供你在运行代码时得到的回溯吗? –

1

一个基本的方法:

  • n字符其中nlen(ptn)
  • 计数多少个字符是每个组块之间相同的连续stn块和ptn
  • 开始如何对这些多少是一个字符不同于len(ptn)

如:

stn = 'KLHLHLHKPLHLHLPHHKLHKLPKPH' 
pat = 'KLH' 

n_combos = zip(*[stn[n:] for n in range(len(pat))]) 
m_counts = (sum(1 for i, j in zip(el, pat) if i == j) for el in n_combos) 
indices = [idx for idx, val in enumerate(m_counts) if val >= len(pat) - 1] 
# [0, 2, 4, 8, 10, 17, 20, 23] 
+0

感谢您的回答。如果我需要最频繁的拍拍(一定长度L),那么我可以用这个位置替换拍拍变量吗? L = 3最大= 0 maxpatt = []中m_counts.iteritems() 为P,F: 如果f>最大: maxpatt = [P] 最大= F 的elif˚F==最大: maxpatt + = [p] –