2016-12-19 4 views
1

파이썬의 SequenceMatcher을 사용하여 두 문자열 사이에 일치하는 블록을 찾으려고합니다. 문자열은 "ABCDPQRUVWXYZ""PQRABCDUVWXYZ"입니다. 그러나 get_matching_blocks()을 적용하면 "PQR" 문자열이 일치하는 블록으로 발견되지 않습니다.파이썬의 시퀀스 매처가 불완전한 일치를 제공합니다

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" 경기를 위해 "P" 인덱스 다시는 "ABCD" 경기를 위해 "A" 인덱스에서 이동하는 것처럼

기능이 예에서 "PQR"을 반환하는 경우

j는 일정하게 증가하지 않을 것입니다.

+0

질문의 코드 조각에서 시도하십시오 : – Faisal

+0

죄송합니다, 내 이전 의견을 계속 : s1 = "ABCPQRSTUVWX"및 s2 = "PQRSTABCUVWX"시도하십시오. 이제 "ABC"는 일반적인 하위 문자열이 없기 때문에 get_matching_blocks() 문제는 "i"및 "j"의 단조 증가 또는 감소와 관련이 없다고 생각합니다. 사실, 단조로운 증가는 공통 부분 문자열 내의 인덱스와 관련이 있다고 생각합니다. – Faisal

+0

맞아요. pqrst가 먼저 발견 되었기 때문에 s1의 abc로 돌아 가면 색인은 비 단조가됩니다. – innisfree

0

감사를 내 게시물에 답변 한 모든 코더에게.

은 용액으로서, I는 실험과

SequenceMatcher's find_longest_match() 

방법을 사용하여 다른 해결책을 찾아 냈다. 이것은 기본적으로 두 문자열 사이의 가장 긴 일치를 반복적으로 찾은 다음 일치하는 가장 긴 문자열을 매번 가비지 문자로 바꾸는 것으로 구성됩니다. 이것도 잘 작동합니다.

관련 문제