2010-03-17 3 views
2

정규식을 입력으로 사용하려고하는데 거기에서 정규식과 일치하는 모든 가능한 값을 생성합니다.정규식을 파이썬에서 일치시킬 수있는 값 목록을 생성합니다.

예를 들어, 정규 표현식이 "a로 시작하고 c로 끝나는 3 문자 단어"인 경우 코드는 [aac, abc, acc, adc, a1c ..] 값의 목록을 생성합니다. ..].

쉬운 방법이 있나요? 파이썬을 사용하고 있습니다.

+0

일부 결과 집합은 거대합니다. –

+3

일부 결과 집합은 무한 할 것입니다. –

+0

그래, 사람들이 원하는 정규 표현식을 넣은 다음 얼마나 많은 히트가 있는지 테스트 할 계획이다. 지정된 숫자 이상인 경우 오류가 발생합니다. – mlissner

답변

7

다음은 작동해야하는 강력한 솔루션입니다. 그것은 실행 시간이 O (L^max_length) (여기서 L은 알파벳의 크기 임)이므로, 위험을 감수하면서 사용하십시오.

def all_matching_strings(alphabet, max_length, regex): 
"""Find the list of all strings over 'alphabet' of length up to 'max_length' that match 'regex'""" 

if max_length == 0: return 

L = len(alphabet) 
for N in range(1, max_length+1): 
    indices = [0]*N 
    for z in xrange(L**N): 
     r = ''.join(alphabet[i] for i in indices) 
     if regex.match(r):     
      yield(r) 

     i = 0 
     indices[i] += 1 
     while (i<N) and (indices[i]==L): 
      indices[i] = 0 
      i += 1 
      if i<N: indices[i] += 1 

return 

사용 예 :

alphabet = 'abcdef1234567890' 
import re 
regex = re.compile('f*[1-3]+$') 
for r in all_matching_strings(alphabet, 5, regex): 
    print r 

것 길이 5 모든 문자열 업, F의 일련의 후 1-3의 비어 있지 않은 순서로 시작하는 출력 후 종료 :

1 
2 
3 
f1 
11 
21 
31 
f2 
12 
22 
32 
f3 
13 
23 
33 
ff1 
[more output omitted...] 
+0

일치하지 않을 수도 있기 때문에 알파벳 문자열에서 정규식에서 전혀 발생하지 않는 문자를 필터링하여 속도를 높일 수 있습니다. 또한 정규 표현식이 알파벳에없는 문자와 일치해야하는지 확인할 수 있습니다. 그렇다면 성공할 수 없으므로 빈 목록을 반환하십시오. 그보다 더 복잡합니다. 항상 일치해야하는 문자 만 고려해야하기 때문입니다. 귀하의 예제에서 정규식은 'x * [1-3] + $'이지만 x * [1-3] + $ '인 경우가 아닙니다. –

+0

이것은 합리적인 해결책처럼 보입니다. 차라리 내 알파벳을 정의 할 필요는 없지만 필요하다고 생각합니다. – mlissner

4

당신은 이것을 원하지 않습니다. 대부분의 결과 세트는 거대하고 일부는 무한합니다. 대신 테스트 벡터의 시퀀스를 사용하여 차례로 각각에 대해 정규식을 적용

vectors = (
    'foo', 
    'bar', 
    ... 
) 

for result in (re.match(someregex, entry) for entry in vectors): 
    ... 
0

일부 정규 표현식은 입력 문자열의 유한 수와 일치하지만, 많은 (대부분?) 입력 문자열의 무한한 수를 일치합니다. 이것은 '파이썬 언어 문법이 주어지면 가능한 모든 파이썬 프로그램을 생성'하는 것과 비슷합니다. 시도한 경우 순차적으로 모두 나열하는 프로그램을 작성할 수 있지만 (실행하는 데 무한한 시간이 걸릴 수 있지만) 정말로 원하십니까? 왜 그러고 싶니?

표준 라이브러리의 정규 표현식 엔진이 원하는 출력을 생성하는 방법을 공개하지 않는다고 확신합니다. 내부 데이터 구조에 대한보다 낮은 수준의 액세스를 확보하거나 직접 DFA 엔진을 구현해야합니다.

1

정규 표현식에 한정 기호 (+ 또는 *)가있는 경우에만 일치하는 문자열 세트가 무한합니다. 귀하의 질문은 그 패턴을 목표로하지 않는 것 같습니다. 오히려 itertoolsproduct 기능이 도움이 될 수 있다고 생각합니다.

당신은 예를 들어 임의의 문자를 나타내는 특수 문자 (예 : 밑줄),이

patt = 'a_c' 

같은 패턴을 구축하고 알파벳

youralphabet = 'abcde...' 

정의를 소개하고 함수를 정의 할 수 있습니다 이

def genInstances(patt): 
    elems = [c if c != '_' else youralphabet for c in patt] 
    return itertools.product(*elems) 

당신은 할 수있다처럼 모든 가능한 인스턴스를 생성 \d 또는 [a-zA-Z] 또는 그 밖의 패턴을 파싱하여 실제 정규 표현식과 일치하도록이 방법을 확장하십시오.

관련 문제