2012-02-15 2 views
3

일치하는 괄호를 포함 할 가능성이있는 문자열에서 일치하지 않는 중괄호 (여는 또는 닫음)를 찾을 수있는 정규 표현식이 필요합니다.일치하지 않는 괄호를 찾으려면 Regex

여기에 stackoverflow에 질문이 있지만 정규식 기반 솔루션을 찾지 못했습니다.

나는 부정적 선견지명을 사용하여 일치하지 않는 열린 중괄호 \((?![^)]+\))을 찾은 정규식을 생각해 냈습니다. 그러나 필적 할 수없는 닫는 중괄호에 필요한 반대 구절을 찾아 낼 수 없습니다.

편집 : 의도 한대로 작동하지 않습니다 타의 추종을 불허하는 열린 중괄호를 찾을 수 위의 정규식. 예 : 그것은 열려있는 여러 중괄호가 하나의 닫는 중괄호 뒤에되는 경우를 (또한 코멘트 참조)

다음

내가 Rubular 나에 대한 실험을 봤는데 내 테스트 문자열 그리워합니다 :

one) ((two) (three) four) (five))) 

참고 문자열에는 따옴표, 대시 등 모든 유형의 문자가 포함될 수 있습니다.

+4

일반적인 경우에는 작동하는 정규식 기반 솔루션이 없기 때문입니다. 그것은 당신이 [regex로 XML을 파싱 할 수 없다] (http://stackoverflow.com/a/1732454/13) (다시 일반적인 경우)와 같은 이유입니다. –

+1

정말 정규 표현식이어야합니까? 왜 'string.each_char {| c | ...}'? –

+2

엄격한 regexp 언어는 할 수 없습니다 .. 그러나 PCRE와 같은 일반적인 확장 정규 표현식은 가능할 수 있습니다. http://stackoverflow.com/questions/562606/regex-for-checking-if-a-string-has-mismatched- 괄호 – Kaganar

답변

8

짧은 대답은 정규 표현식과 일치하지 않는 괄호를 찾을 수 없다는 것입니다. 정규 표현식은 regular languages을 인코딩하지만 올바르게 일치하는 모든 괄호의 언어는 context-free language입니다.

4

여기 LALR HTML을 포함하여 (N) 문법, 구문 분석 할 수있는 정렬-의 정규식 기반 솔루션 :

def balanced?(str, open='(', close=')') 
    re = Regexp.new("[\\#{open}\\#{close}]") 
    str.scan(re).inject(0) do |lv,c| 
    break :overclosed if lv < 0 
    lv + (c==open ? 1 : -1) 
    end == 0 
end 

s1 = "one) ((two) (three) four) (five)))" 
s2 = "((one) ((two) (three) four) (five))" 
s3 = "((one) ((two) (three) four) (five)" 

puts balanced?(s1), #=> false 
    balanced?(s2), #=> true 
    balanced?(s3) #=> false 
+0

니스, 고마워요 :) –

1

루비의 Oniguruma 라이브러리입니다. README 인용 :

r = Regexp.compile(<<'__REGEXP__'.strip, Regexp::EXTENDED) 
    (?<element> \g<stag> \g<content>* \g<etag>){0} 
    (?<stag> < \g<name> \s* >){0} 
    (?<name> [a-zA-Z_:]+){0} 
    (?<content> [^<&]+ (\g<element> | [^<&]+)*){0} 
    (?<etag> </ \k<name+1> >){0} 
    \g<element> 
    __REGEXP__ 

    p r.match('<foo>f<bar>bbb</bar>f</foo>').captures 

위의 코드 것은 물론 훨씬 간단 진짜 HTML 파서보다,하지만 중첩 된 태그를 일치합니다. 또한 매우 느릴 수있는 정규 표현식을 작성하는 것은 매우 간단하다는 점에 유의해야합니다 (80- 기호 문자열을 구문 분석하는 데 분 단위의 범위 내에서).

이 작업에는 Treetop과 같은 실제 파서를 사용하는 것이 좋습니다.

관련 문제