2012-05-19 5 views
1

이것은, 지금 내 코드입니다파이썬 정규식 ~ 간단한 문제

import re 
matches = re.search(r'^%s\s*\((.*?)\)'%"Hello", "Hello(Hi())") 
print matches.group(1) 

이의 안녕을 참조 후 그것은 괄호 안의 모든 것을 가져옵니다. 그래서 예를 들어 ,

Hello(hi) produces hi 

나는 한 가지 문제가 있어요,

Hello(Hi()) produces Hi(and not Hi() 

사람이 내가 정규식을 변경하여이 문제를 해결할 수있는 방법을 알고 있나요?

+0

중첩 된 괄호가 일반 언어를 형성하지 않기 때문에 임의로 중첩 된 괄호와 일반 epxress를 일치시키는 것은 일반적으로 불가능합니다. 중첩에 대한 상한선을 보장 할 수 있습니까? –

+1

최종 괄호가 어떻게 든 고유하다는 것을 보장 할 수 있다면 (예 : 줄 끝에서 공백 (및 닫힌 괄호)이 아닌 경우) 정규 표현식의 끝을 앵커 할 수 있습니다. – larsks

+0

왜 라인 앵커의 시작으로 검색을 사용하고 있습니까? 이것은보다 느린 것을 제외하고는 match를 사용하는 것과 같습니다. –

답변

3

을 모두 당신을 경우 에 대한 가장 바깥 쪽 괄호 안에 무엇이며 치료 후 $ 앵커 사용하면 중첩 된 괄호를 일치 시키려면

>>> re.match("Hello\((.*)\)$", "Hello(Hi())").group(1) 
'Hi()' 
>>> re.match("Hello\((.*)\)$", "Hello(Hi(Bye()))").group(1) 
'Hi(Bye())' 

을, 귀하의 언어는 context-free이지만 regular이 아니기 때문에 RE는 불가능합니다. 대신 정규 표현식 결과에 반복적으로 regexes를 적용 할 수 있습니다.

+3

+1 가능하다면 가장 바깥 쪽 괄호 뒤에 무언가를 매치하는 것을 좋아합니다. 그러나'*? '에 대한 주석은 여러분의 구체적인 예에 ​​적용되지 않습니다. 기본적으로'.'는 새로운 줄과 매치하지 않기 때문에'*'도 사용할 수 있습니다. 비록 당신이 공간과 일치하는 경우, 예를 들어 필요합니다. –

+0

이 하나가 조금 더 효과가 있음을 알았습니다. 감사합니다. – user1357159

+0

마크와 동의합니다. '*? '는 정규 표현식이 작동하는 이유와 아무 관련이 없습니다. '$'는 답안의 주요 아이디어입니다. –

1

임의의 수준의 중첩이있을 수있는 경우 정규식은 부적절합니다.

당신은 해결 될 수 중첩 결코 더 둘 이상의 수준이 될 것이라고 확신 할 수 있지만, 적절한 아닌 경우 :

re.match(r'^%s\s*\(((?:[^()]*|\([^)]*\))*)\)' % re.escape("Hello"), text) 

온라인으로 작업을 참조하십시오 ideone

+0

... 이제 두 가지 문제가 있습니다. –