2016-07-18 2 views
1

파이썬에서 웹 트래픽을 검사하는 정규 표현식 정규 표현식을 사용합니다. 문제는 페이지가 1MB보다 크고 단일 문자열로 구성되어있는 경우 정규식 완료까지 걸리는 경우가 종종 있습니다. 최대 실행 시간 제한을 설정하는 방법이 있는지 궁금하네요?파이썬 최대 실행 시간 초과 또는 정규식 가속화

내 스크립트 파일에서 정규 표현식에를 읽은 다음 그들에게 한 번에 하나씩 처리합니다

def match_keywords_add_to_es(pastes): 
    match_list = get_re_match_list() 
    for paste in pastes: 
     log.info("matching %s"%paste["key"]) 
     for match in match_list: 
      matched = match[1].findall(paste["raw"].lower()) 
      if len(matched) > 0: 
       try: 
        paste["keywords"] = match[0] 
        res_paste = Paste(dictionary=paste) 
        Paste.add_paste(res_paste) 
       except Exception,e: 
        log.error("Failed to add the paste "+str(paste)+" with error %s"%e) 

예는 정규 표현식에 : 나는 하나의이 부분에 초점을 맞출거야

secret_key: 
    match: .*secret(_)?key\s*=\s*(.*)?[A-Za-z0-9\/]{40}(.*)?.* 

access_key: 
    match: .*access(_)?key\*=\*(.*)?[A-Z0-9]{20}(.*)?.* 

example.com: 
    match: .*example\.com.* 
+0

당신이 시도한 방법을보기 위해 코드를 보여주십시오. –

+0

@ MarkoMackic included –

+0

정규 표현식을 볼 수 없다면 정규 표현식을 더 빠르게 만들 수 없습니다. 그러나 정규 표현식이 너무 많은 시간을 들여야한다는 것을 알아 내면 도움이 될 것입니다. – Kevin

답변

3

을 당신의 regexen : 첫째

\s*(.*)?[A-Za-z0-9\/]{40}(.*)?.* 

, \s*(.*)?. 이 문제는 \s*이 공백을 역행시킨 다음 (.*)?에 의해 소비되도록 할 수 있습니다 (물음표도 필요 없음). 결과적으로 여러분의 정규 표현식이 멀리까지 도달했지만 나머지 라인에서는 일치하지 않으면 완전히 쓸모없는 백 트랙킹을 많이 받게됩니다.

\s*(\S.*|) 

이 하나의 비 공백 문자 아무것도 다음에, 또는 일치 : 당신은 아마 가능한 한 많은 공백을 일치하도록 \s을 강제로 .보다 더 제한적인 것을 사용하고 다시 포기를 거부 할 빈 문자열. \s으로 역행하는 공백을 소비 할 수 없기 때문에 역 추적이 덜 고통 스러울 것입니다.

앞서 건너 뛰어도이 건설은 완전히 당황한 것입니다 : (.*)?.*. 첫 번째 점 스타는 줄의 나머지 문자를 모두 소비하므로 두 번째 별은 필요하지 않습니다. Star는 0 번 발생과도 일치 할 수 있으므로이 경우 물음표가 필요하지 않습니다.

Wiktor Stribiżew가 의견에서 지적한대로 /도 탈출 할 필요가 없습니다.

그래서 개정 된 단편은 다음과 같습니다

\s*(\S.*|)[A-Za-z0-9/]{40}(.*) 

최종 참고로, 나는 (단 하나) 일을 제안 게으른 (.*) 서열, 나는 그것이 어렵게 여부를 추론 할 찾을 수 있기 때문에 첫 번째 부분이 [A-Za-z0-9\/]{40} 또는 일치하는 줄의 마지막 부분과 일치합니다. I 두 번째 게으른 만들기는 정규식의 의미를 변경하지 않을 것이라고 믿지만, 100 % 확신 할 수는 없으므로 테스트 해보십시오.

+0

파이썬은'? +','* +','++','{1,250} +'과 같은 소유량 한정자를 지원하지 않으므로'/'를 이스케이프 할 필요가 없습니다. –

+0

@ WiktorStribiżew : 좋은 지적. 나는 그것을했을 것이라고 맹세 할 수는 있었지만,'re'문서 페이지 어디에서도 찾을 수 없었다 ... – Kevin

+0

두 번째'. *'가 게으른 경우 @Kevin, 빈 문자열과 항상 매치한다. 더 많은 일치를 유도하는 구조가 뒤 따르지 않습니다. 탐욕스러운'.*'는 줄 끝까지 일치합니다. –