2010-04-15 2 views
3

템플릿 표현식에 포함 된 이스케이프 된 물음표 (\?)를 발견 할 때까지 이상한 기존 클라이언트 템플릿을 구문 분석하기 위해 꽤 잘 작동하는 PHP 정규식이 있습니다. 나는 약한 국수를 네가티브 한 표정이나 테크노 - 불만스런 점보를 감싸는 정규 표현식으로 충분히 강하지 않으므로 올바른 방향으로 팁이나 포인트를 높이 평가할 것이다.정규 표현식을 사용하여? 하지만 아니?

내 PHP :

나는이 질문을 게시 할 때
preg_match_all("/\{\{IF (.*)\?(.*):(.*)\}\}/U", $template, $m, PREG_SET_ORDER); 

좋아, 조금 압도했다. 그것을 적절한 상황에 넣을 수있게하십시오.

템플릿 코드는 다음과 같습니다 : 나는 현재 거의가 아니라 완전히 제 기능이를 달성하고

if ($template[$var]) { 
echo "SHOW: THIS?"; 
} else { 
echo "SHOW ".$template['ELSE']; 
} 

:

{{IF VAR?"SHOW: THIS?":"SHOW {{ELSE}}"}} 

로서 해석 할 수 있어야한다.

preg_match_all("/\{\{IF ((?:[^\\?]|\\.)*)\?((?:[^\\:]|\\.)*):(.*)\}\}[^<\/]/", $template, $m, PREG_SET_ORDER); 
if (count($m)) { 
foreach ($m as $o) { 
    if (preg_match("/(.*)\s+(==|!=)\s+(.*)/", $o[1], $x)) { 
    if (preg_match("/^\"(.*)\"/", $x[1], $cx)) $e1 = $cx[1]; 
    else $e1 = is_numeric($x[1])?$x[1]:$data[$x[1]]; 
    if (preg_match("/^\"(.*)\"/", $x[3], $cx)) $e2 = $cx[1]; 
    else $e2 = is_numeric($x[3])?$x[3]:$data[$x[3]]; 
    if (preg_match("/^\"(.*)\"/", $o[2], $ox)) $er[0] = $ox[1]; 
    else $er[0] = addslashes(htmlspecialchars($data[$o[2]])); 
    if (preg_match("/^\"(.*)\"/", $o[3], $ox)) $er[1] = $ox[1]; 
    else $er[1] = addslashes(htmlspecialchars($data[$o[3]])); 
    $eval = "\$od = (\"$e1\" $x[2] \"$e2\")?\"$er[0]\":\"$er[1]\";"; 
    eval($eval); 
    } else { 
    $od = $data[$o[1]]?$o[2]:$o[3]; 
    if (preg_match("/^\"(.*)\"/", $od, $x)) $od = $x[1]; 
    else $od = $data[$od]; 
    } 
    $template = str_replace($o[0], $od, $template); 
} 
} 

if (is_array($data)) 
foreach ($data as $k => $v) $template = str_replace('{{'.$k.'}}', $v, $template); 
return $template; 
+0

또한 콜론 (:)에도 적용 할 수있는 솔루션을 찾고 있습니다. – Millions

+0

관련 물음표는 어디에 있습니까? – cletus

+0

좋아, 나는이 질문을 올렸을 때 약간 압도 당했다. 그것을 적절한 상황에 넣을 수있게하십시오. 템플릿 코드는 다음과 같습니다 {? {IF VAR "SHOW :이?"} "{{ELSE}} SHOW"} 가 있어야한다 : 경우 ($ 템플릿 [$ var에]) { \t \t echo "SHOW : 이거?"; \t} else { \t \t echo "SHOW". $ template [ 'THIS']; \t} 저는 현재이 기능을 거의 구현하고 있지만 전체적으로는 아닙니다. 이것은 다음과 같은 함수입니다 : http://snipplr.com/view/31855/a-ninja-funerals/ – Millions

답변

1

당신은 당신의 (.*) 지역 — 더 이상 사실 당신은 아무것도의 순서와 일치하도록 없다을 변경해야
(.*)[^\\]\?(.*) 
+0

그 줄이 a로 시작하는 줄과 일치하지 않습니까? 그래도. 다른 것을 추가해야합니다. 그게 당신이 처리해야 할 사건입니까? – Chris

2

:이 기능입니다. 대신, 이스케이프되지 않은 문자 또는 이스케이프 시퀀스의 시퀀스를 일치 시키려합니다. ((?:[^\\]|\\.)*) 역 슬래시 이스케이프가 포함 된 문자열과 일치합니다. 당신이 물음표 나 콜론과 일치하지 않기를 원한다는 것을 지정함으로써 성능을 향상시킬 수 있다고 생각합니다. 이렇게하면 정규식 /\{\{IF ((?:[^\\?]|\\.)*)\?((?:[^\\:]|\\.)*):(.*)\}\}/으로 끝납니다. 저것은 더러운 것처럼 보입니다 만, 저는 여러분의 (.*)을 위의 구성으로 대체했습니다. 꽤 간단합니다.

+0

더 좋은 ... 따뜻한. 나는 처음으로 내 질문에 대해 더 잘 표현하고 싶다. – Millions

1

다음은 효과가 있습니다. 올바른 방향으로 포인트를 주신 @ absz에게 감사드립니다.

preg_match_all("/\{\{IF ([^\"\\]]*(\\.[^\"\\]]*)*)\?((?:[^\\:]|\\.)*):(.*)}\}/", $template, $m, PREG_SET_ORDER); 
+0

기꺼이 도와 드리겠습니다. –