2010-07-01 5 views
3

파이썬은 혼란 스럽습니까, 아니면 프로그래머입니까?Python 정규식은 대괄호 ([])로 혼동됩니까?

나는이 라인을 많이 가지고 : 내가하고 싶은 무엇

some_dict[0x2a] = blah 
some_dict[0xab] = blah, blah 

는 다음과 같이 모든 대문자로 진수 코드를 변환하는 것입니다 :

some_dict[0x2A] = blah 
some_dict[0xAB] = blah, blah 

그래서 정규 표현식을 호출하기로했습니다. 일반적으로 나는 편집기의 regexps (xemacs)를 사용하여이 작업을 수행 할 것이지만, 대문자로 변환 할 필요가 있으면 Lisp에 넣을 필요가있다. .... 오케이 ... 파이썬은 어때?

그래서 나는 작동하지 않는 짧은 스크립트를 채집합니다. 코드를이 예제로 요약했는데 작동하지 않습니다. Python의 정규 표현식이 코드의 대괄호로 혼란스러워지고있는 것처럼 보입니다. 나 아니면 파이썬인가?

import fileinput 
import sys 
import re 


this = "0x2a" 
that = "[0x2b]" 

for line in [this, that]: 
    found = re.match("0x([0-9,a-f]{2})", line) 

    if found: 
     print("Found: %s" % found.group(0)) 

(나는() 그룹화를 사용하고 그래서 난 '0X'에서 'x'를 활용하지 않는 구성한다.)

이 예는 단지 0x2a 값이 아닌 0x2b를 인쇄합니다. 이것은 올바른 행동입니까?

난 쉽게에 일치 식을 변경하여이 문제를 해결할 수 있습니다

found = re.match("\[0x([0-9,a-f]{2}\])", line) 

하지만 누군가가 나에게 여기 무슨 일이 일어나고 있는지에 대한 통찰력을 줄 수 있다면 난 그냥 궁금 해서요.

Linux에서 Python 2.6.2 실행.

+1

당신이 알고 있는지'에 특별한 의미가 [''및]' 정규식? 그들은 단지 * 캐릭터가 아니에요? 어떤 정규식 문서를 읽고 있습니까? 나는 당신의'\\ [... \\]'버전 주위에 어떤 방법도 보지 못했다. 어떤 문제가 있습니까? –

+1

당신은 문자 클래스'[0-9a-b]'가 잘 동작 할 필요가 없습니다. – fbstj

+0

@FallingBullets : 알아두면 좋을 것. 감사! –

답변

7

re.match 문자열의 시작과 일치합니다. "문자열의 첫 번째 어커런스와 일치 시키려면"대신 re.search을 사용하십시오. 문서의 핵심 비트는 here입니다.

+0

아, 그렇게 간단합니다. 더러운 단어들! 고마워, 알렉스. –

+0

@JS, 오신 것을 환영합니다! –

4

대괄호 안에 쉼표가 필요하지 않다고 생각합니다. ie :

found = re.match("0x([0-9,a-f]{2})", line) 

은 실수로 빗 나갈 수있는 쉼표를 찾도록 알려줍니다. 원하는 것 같아

found = re.match("0x([0-9a-f]{2})", line) 
+0

이것은 질문에 대답하지 않기 때문에 주석이어야합니다. – fbstj

+0

아직 코멘트를 남길만큼 충분한 평판이 없습니다. 죄송합니다. – PerilousApricot

+0

아, 괜찮습니다. 죄송합니다 자신 : D – fbstj

4

부분 패턴을 사용 중이므로 전체 입력 문자열과 일치해야하는 re.match을 사용할 수 없습니다. 부분 일치를 수행 할 수있는 re.search을 사용해야합니다.

>>> that = "[0x2b]" 
>>> m = re.search("0x([0-9,a-f]{2})", that) 
>>> m.group() 
'0x2b' 
+0

re.match는 전체 입력 문자열과 일치 할 것으로 기대하지 않습니다. 문자열의 시작 부분에서 일치를 시도합니다. 전체 문자열과 일치 시키려면'r "\ Z"(* NOT *' "$"')를 패턴에 추가해야합니다. –

2

당신은 만에 실패 문자열의 시작 부분에서 일치합니다

found = re.match("0x([0-9,a-f]{2})", line) 

re.match

found = re.search("0x([0-9,a-f]{2})", line) 

에 변경하려는거야 " [0x2b] ".

re.search 무시하여 문자열 어디서나 일치 할 것이다 선도 "["를 "[0x2b]"경우이다.

자세한 내용은 search() vs. match()을 참조하십시오. 당신의 re.sub를 사용하고 대체 문자열로 호출을 전달하면

+0

re.match는 전체 입력 문자열과 일치 할 것으로 기대하지 않습니다. 문자열의 시작 부분에서 일치를 시도합니다. 전체 문자열을 일치 시키려면 패턴에 r "\ Z"("$"가 아님)을 추가해야합니다. –

+0

이에 따라 업데이트됩니다. 감사. – bvanvugt

1

, 그것은 또한 당신을 위해 uppercasing을 수행합니다

>>> that = 'some_dict[0x2a] = blah' 
>>> m = re.sub("0x([0-9,a-f]{2})", lambda x: "0x"+x.group(1).upper(), that) 
>>> m 
'some_dict[0x2A] = blah'