2013-04-25 2 views
3

나는 내 인생을 여러 번 둘러 보는 방법을 알아낼 수 없습니다. 해시 다음에 오는 숫자의 가변 개수를 일치 시키려고하지만 어떤 것이 앞에 나오거나 다른 것이 따르는 경우가 아니라고 가정 해보십시오. 예를 들어, 다음에서 # 123 또는 # 12345와 일치시키고 싶습니다. lookbehinds 괜찮아 보이지만 lookaheads하지 않습니다. 나는 아이디어가 없어.여러 부정적인 표제 어설 션

matches = ["#123", "This is #12345", 
      # But not 
      "bad #123", "No match #12345", "This is #123-ubuntu", 
      "This is #123 0x08"] 

pat = '(?<!bad)(?<!No match)(#[0-9]+)(?! 0x0)(?!-ubuntu)' 

for i in matches: 
    print i, re.search(pat, i) 

답변

3

캡쳐도 살펴야합니다. 난 당신이 얻을 것이다 마지막 두 개의 문자열을 내기 :

엔진은 두 lookbehinds 확인 - 그들이 일치하지 않습니다, 그것은 캡처 그룹 #[0-9]+과 일치 계속 그래서 :

#12 

이 일어나는 것이다 #123. 이제는 선견자를 확인합니다. 그들은 원하는대로 실패합니다. 하지만 지금은 역 추적이 있습니다! 패턴에 하나의 변수가 있으며 그 변수는 +입니다. 따라서 엔진은 마지막으로 일치하는 문자 (3)를 버리고 다시 시도합니다. 이제 선견자들은 더 이상 문제가 없으며 당신은 성냥을 얻습니다. 이 문제를 해결하는 가장 간단한 방법은 당신이 마지막 자리로 이동해야합니다 다른 내다 추가하는 것입니다

pat = r'(?<!bad)(?<!No match)(#[0-9]+)(?![0-9])(?! 0x0)(?!-ubuntu)' 

참고 원시 문자열 (주요 r)의 사용을 - 그것은이 패턴에 문제가되지 않습니다 , 일반적으로 좋은 습관입니다. 왜냐하면 일단 문자를 이스케이프하기 시작하면 일이 추해지기 때문입니다.

편집 : 당신이 사용하거나 대신 reregex 패키지를 사용하고자하는 경우에는 되돌아를 억제 소유 한정사를 얻을 :

pat = r'(?<!bad)(?<!No match)(#[0-9]++)(?! 0x0)(?!-ubuntu)' 

그것은 당신이 더 읽기 쉽고 유지 보수가 찾을 수있는 당신에게 달려 있습니다. 하지만 후자는 더 효율적입니다. (크레딧은 regex 패키지를 가리키는 데 nhahtdh로 이동합니다.)

+0

파이썬're'에는 소유량 한정어가 없습니다. – nhahtdh

+0

@nhahtdh가 인터넷 검색을하고 실현하고 편집했습니다. 어쨌든 고마워! :) –

+0

나는'regex' 패키지가 가지고 있다고 믿지만 (그것은 소유량 한정자보다 훨씬 더 애호가를 지원한다). – nhahtdh