2016-12-19 6 views
1

Я пытаюсь найти соответствующие блоки между двумя строками, используя Python's SequenceMatcher. Строки: "ABCDPQRUVWXYZ" и "PQRABCDUVWXYZ". Однако, когда я применяю get_matching_blocks(), строка "PQR" не найдена как соответствующий блок.Последовательность последовательностей Python дает неполное соответствие

from difflib import SequenceMatcher 

str1 = "ABCDPQRUVWXYZ" 
str2 = "PQRABCDUVWXYZ" 

matchAll = SequenceMatcher(None, str1, str2, False).get_matching_blocks() 

for i in range(0, len(matchAll)): 
    print(str1[matchAll[i].a: matchAll[i].a + matchAll[i].size]) 
+0

Почему вы ожидали найти 'PQR'? Похоже, задача, которую вы хотите выполнить, - это не задача «difflib.SequenceMatcher». – user2357112

+0

использует 'difflib.SequenceMatcher' требование для правильной маркировки ответа? Вы обязаны использовать эту библиотеку? – s2t2

+0

docs: https://docs.python.org/2/library/difflib.html#difflib.SequenceMatcher.get_matching_blocks – innisfree

ответ

0

Это может делать то, что вы хотите - не найти перекрывающихся матчи, хотя (пересмотрено с целью включения местоположения строки в s1 и s2 из подстрок):

str1 = "ABCDEPQRUVWXYZ" # added extra non-matching character 
str2 = "PQRABCDUVWXYZ" 

def find_subs(s1, s2): 
    subs = [] 
    loc = 0 
    while s1: 
     s1_copy = s1 
     while s1_copy: 
      while s1_copy and s1_copy not in s2: 
       s1_copy = s1_copy[:-1] 
      if s1_copy: 
       subs.append((loc, s2.index(s1_copy), s1_copy)) 
       loc += len(s1_copy) 
       s1 = s1[len(s1_copy):] 
      else: 
       s1 = s1[1:] 
       loc += 1 
      s1_copy = s1     
    return subs 

print(find_subs(str1, str2)) 

принты:

[(0, 3, 'ABCD'), (5, 0, 'PQR'), (8, 7, 'UVWXYZ')] 
+0

Спасибо за решение, оно действительно работает. – Faisal

1

В docs утверждают, что:

get_matching_blocks()

Возврат список троек, описывающих соответствующие подпоследовательности. Каждая тройка имеет вид (i, j, n) и означает, что a [i: i + n] == b [j: j + n]. Тройки монотонно возрастают в i и j.

Если функция вернула "PQR" в вашем примере, j не будет монотонно возрастает, так как она будет идти из индекса "A" для "ABCD" матча, обратно к индексу "P" для "PQR" матча.

+0

В фрагменте кода в вопрос, попробуйте: – Faisal

+0

Извините, в продолжение моего предыдущего комментария попробуйте: s1 = "ABCPQRSTUVWX" и s2 = "PQRSTABCUVWX". Теперь «ABC» - это обычная подстрока, которая не найдена, поэтому я не думаю, что проблема с get_matching_blocks() связана с монотонным увеличением или уменьшением «i» и «j». Infact, я думаю, что монотонное увеличение связано с индексами внутри общей подстроки, а не за ее пределами. – Faisal

+0

Правильно, потому что сначала найден pqrst, поэтому индекс i будет немонотонным, если он вернется к abc в s1 – innisfree

0

Спасибо для всех кодеров, которые ответили на мой пост.

В качестве решения, я экспериментировал и нашел другое решение с использованием

SequenceMatcher's find_longest_match() 

метода. Это состоит в том, чтобы в основном находить самое длинное совпадение между двумя строками многократно, а затем путем замены согласованной длинной строки каждый раз символами мусора. Это хорошо работает.

 Смежные вопросы

  • Нет связанных вопросов^_^