2012-03-30 2 views
1

중괄호 안에 코드의 일부를 잡기 위해 일종의 정규 표현식이 필요합니다. 이에 대해 다른 질문이 있지만 내 것은 조금 다릅니다.중괄호 안의 코드를 올바르게 잡는 방법은 무엇입니까?

이 코드를 샘플로 간주하십시오.

public function my_method($my_input) { 
    if(true == false) { $me = "Forever alone. :("; } 
    if(true == true) { $me = "No longer alone. :}"; } 
    if(false == false) { $me = ":{ - This is so Wrong."; } 
} 

하고 "공공 기능 my_method ($ my_input)"부분을 무시합니다.

if(true == false) { $me = "Forever alone. :("; } 
    if(true == true) { $me = "No longer alone. :}"; } 
    if(false == false) { $me = ":{ - This is so Wrong."; } 

"{"및 "}"문자가 문자열 (및 코멘트 등) 내에 오도 될 수 있으므로 어떻게 잡을 수 있습니까?

정규 표현식에 대한 지식이 매우 부족하며이를 달성하는 데 어려움이 있습니다. :/

+0

PHP 코드를 구문 분석 하시겠습니까? – alexn

+0

정규식으로 HTML을 파싱 할 수없는 것과 같은 이유에서 작동하지 않을 것입니다. PHP 나 HTML도 일반 언어가 아닙니다. – moodywoody

+0

편집 방법을 내부 메서드로만 제한하는 코드 편집기를 작성/개발하려고합니다. – Diabolic

답변

3

큰 따옴표가 역 슬래시 인 경우에도 대부분의 경우에 통과하는 정규식을 만들었습니다. 다음은 예제 스크립트입니다. 나는 정규 표현식에 주석을 제공했는데, 정규 표현식에서 모든 문자열을 역 슬레쉬해야했는데, 정규 표현식 자체의 문자열 구분 기호로 사용했기 때문이다.

정규식은 재귀 적이므로 대괄호가 중첩 된 깊이 수준에 제한이 없습니다. 그러나 대괄호 (즉, 대괄호 없음)에 오류가있을 수는 없지만 논리적입니다.

$str = 
' 

public function my_method($my_input) { 
    if(true == false) { $me = "Forever alone. :("; } 
    if(true == true) { $me = "No longer alone. :}"; } 
    if(true == true) { $me = \'No longer alone. :}\'; } 
    if(true == true) { $me = \'No longer \\\' alone. :}\'; } 
    if(false == false) { $me = ":{ - This is so Wrong."; } 
} 

public function my_method($my_input) { 
    if(true == false) { $me = "Forever happy. :("; } 
    if(true == true) { $me = "No longer happy. :}"; } 
    if(true == true) { $me = \'No longer happy. :}\'; } 
    if(true == true) { $me = \'No longer \\\' happy. :}\'; } 
    if(false == false) { $me = ":{ - This is so Wrong."; } 
} 

'; 

preg_match_all(
    '/ 
     {        # opening { 
     (       # matching parentheses 
      (?:      # non matching parentheses 
       (?:      # non matching parentheses 
        [^{}"\']+   # anything but { } " and \' 
        |     # or 
        "     # opening " 
        (?:    # non matching parentheses 
         [^"\\\]*  # anything but " and \ 
         |    # or 
         \\\"   # a \ followed by a " 
        )*    # as often as possible 
        "     # closing " 
        |     # or 
        \'     # opening \' 
        (?:    # non matching parentheses 
         [^\'\\\\]*  # anything but \' and \ 
         |    # or 
         \\\\\'   # a \ followed by a \' 
        )*    # as often as possible 
        \'     # closing \' 
       )*      # as often as possible 
       |      # or 
       (?R)     # repeat the whole pattern 
      )*       # as often as possible 
     )        # close matching parentheses 
     }        # closing } 
    /xs', 
    $str, 
    $matches 
); 

print_r($matches); 
+0

최대한 빨리 테스트 해 보겠습니다. 오, 하나님, 그것이 작동하면 멋지다! – Diabolic

+0

기적적으로 일하십시오! 고마워. ^^ – Diabolic

4

일치하는 괄호는 정규 표현식으로 시도해서는 안되는 프로토 타입 예제 중 하나입니다. 문자열에서 괄호 없이도 정규 표현식을 사용하기에는 너무 복잡합니다.

중첩 된 괄호가있는 (공식적인) 언어가 규칙적이 아니기 때문에 문맥이없는 문법으로 표현되기 때문에 간단한 정규식보다 상당히 복잡합니다. 매우 높은 수준에서 정규 표현식은 "임의의 큰 수까지 셀 수 없습니다."즉, 닫는 괄호가 여는 괄호에 속하는지 인식 할 수 없습니다 (PHP와 같이 임의로 중첩되는 괄호 깊이를 허용하는 한))).

문맥이없는 문법을 지원하는 도구를 움켜 잡고 이미 작성된 일부 PHP 파서를 얻는 것이 좋습니다. 자신을 기능을 추출하기 위해

, 당신은 아마 키워드 function (또는 기능 블록을 나타내는 다른 키워드)에 대한보고, 여는 괄호 ({)로 이동한다. 그런 다음 현재 일치하는 닫는 괄호 (})를 찾을 때까지 문자로 계속 문자를 만들 수 있으며 현재 문자열이나 주석 또는 다른 문자가 있는지 여부를 추적 할 수 있습니다.

그러나, 나는

+0

정보를 제공해 주셔서 감사합니다. 나는 regexp에게 어느 시점까지 시도 할 것이다. 나는 또한 PHP 파서를 동시에 찾고있다. – Diabolic

2

regexps '에 오른쪽되지 않습니다 ... 나는 가능한 모든 코너 케이스를 돌봐 아주 번거로울 수 있습니다 상상할 수 있기 때문에, 자신을 손으로이 작업을 수행 할 원하지 않는 이를위한 도구 - 자세한 내용은 @phimuemue's answer을 참조하십시오 ..

스크립트에는 PHP's own tokenizer을 사용할 수 있습니다. 그러나 단순히 블록의 내부에있는 것이 아니라 블록 내부에있는 토큰을 제공합니다. 원하는 작업에 따라 토큰에서 소스 코드를 재구성해야합니다.

+0

감사합니다.이 정보는 저에게 유익합니다. – Diabolic

관련 문제