2011-07-29 5 views
0

친구 (지금 휴가 중이신 분)에게 도움을 받았지만 preg_replace 검색에 문제가 있습니다. 나는 이유를 모르지만, 문자열을 잘못 대체 한 것이므로 다음에 대체해야 할 영향에 대한 노크가 있습니다.preg_replace가 잘못 대체되었습니다.

기본적으로 이것은 템플릿 내에서 'if'및 'else'쿼리를 처리하는 템플릿 클래스 내에 있습니다.

function if_statement($a, $b, $if, $type, $else = NULL){ 
    if($type == "1" && is_numeric($a) && is_numeric($b)){ 
     $statement = ($a === $b) ? $if : $else; 
    } else if($type == "1"){ 
     $statement = ($a == $b) ? $if : $else; 
    } else if($type == "2"){ 
     $statement = ($a != $b) ? $if : $else; 
    } 
    return stripslashes($statement); 
} 

$output = file_get_contents("template.tpl"); 

$replace = array(
    '#\<if:"\'(.*?)\' == \'(.*?)\'"\>(.*?)\<else\>(.*?)\<\/endif\>#sei', 
    '#\<if:"\'(.*?)\' == \'(.*?)\'"\>(.*?)\<\/endif\>#sei' 
); 
$functions = array(
    "if_statement('\\1', '\\2', '\\3', '1', '\\4')", 
    "if_statement('\\1', '\\2', '\\3', '1')" 
); 
$output = preg_replace($replace, $functions, $output); 
echo $output; 

템플릿 :

<HTML> 
    <head> 
    <meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" /> 
    <title>Site Title</title> 
    <link rel="stylesheet" type="text/css" media="screen" href="common.css" /> 
    <if:"'{ISADMIN}' == '1'"> 
     <link rel="stylesheet" href="admin-bar.css" type="text/css" media="all" /> 
    </endif> 
</head> 
<body> 
    <if:"'{TODAY}' == 'Monday'">Today is Monday<else>Today is not Monday</endif> 
    <if:"'1' == '2'">1 equals 2!<else>1 doesn't equal 2</endif> 
</body> 
</html> 

전류 출력 아래 것이다 : 상기에서

<HTML> 
    <head> 
    <meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" /> 
    <title>Site Title</title> 
    <link rel="stylesheet" type="text/css" media="screen" href="common.css" /> 

     <link rel="stylesheet" href="admin-bar.css" type="text/css" media="all" /> 
    **</endif>** 
</head> 
<body> 
    **<if:"'{TODAY}' == 'Monday'">**Today is Monday 
    1 doesn't equal 2 
</body> 
</html> 

, 굵은/애스 트릭스 makred 부분의 출력에 존재하지 않아야 , 그리고 오늘은 월요일이 아닙니다. 관리자가 로그인하는 동안 admin-bar.css 파일이 올바르게 포함되었지만 어떤 이유에서 </endif> 태그를 가져 오지 않았습니다. 다음 문장 대신 <else> 태그를 찾은 것 같습니다. words, preg_replace가 잘못된 물건과 일치했습니다! 그리고 따라서 2 번째 <if> 성명서를 접하지 못했습니다. 나는 심지어 수동으로 문 (단지 확인)에 데이터를 넣어, 그래서 그들은 문제가되지 않습니다 ...

나는 이유는 모르겠지만, -

{BRACKET} 태그

제대로 대체되고있다 나에게 preg_replace은 올바른 순서를 찾아서 작동하지 않습니다. 누구든지 신선한 눈을 만들거나 손을 빌려줄 수 있다면 감사 할 것입니다.

감사합니다.

답변

3

샘플의 첫 번째 <if><else> 절이 없습니다. <if:"'(.*?)' == '(.*?)'">(.*?)<else>(.*?)</endif>이 (<else>은 선택 아닌 경우)에 적용된 경우 따라서, 모든이 일치 : 일치하는에서

<if:"'{ISADMIN}' == '1'"> 
     <link rel="stylesheet" href="admin-bar.css" type="text/css" media="all" /> 
    </endif> 
</head> 
<body> 
    <if:"'{TODAY}' == 'Monday'">Today is Monday<else>Today is not Monday</endif> 

, 그룹 $3 당신은 그 정규식을 금지함으로써 피할 수

 <link rel="stylesheet" href="admin-bar.css" type="text/css" media="all" /> 
    </endif> 
</head> 
<body> 
    <if:"'{TODAY}' == 'Monday'">Today is Monday 

입니다 주석 형태 (및 더 helpfu에서

'%<if:\s*"\'([^\']*)\' == \'([^\']*)\'">((?:(?!<else>|</endif>).)*)<else>((?:(?!</endif).)*)</endif>%si' 

또는 : 룩어 주장을 이용한 </endif> 위에 교차 프로그래머가 다시) "멀리 휴가"간다 난 :

'%<if:\s*"\'  # Match <if:(optional space)"\' 
    ([^\']*)  # Match 0 or more non-quote characters, capture group 1 
    \'\s==\s\' # Match \' == \' 
    ([^\']*)  # Match 0 or more non-quote characters, capture group 2 
    \'">   # Match \'"> 
    (   # Capture into group 3: 
    (?:   # The following group... 
     (?!  # only if we\'re not right before... 
     <else> # <else> 
     |   # or 
     </endif> # </endif> 
    )   # (End of lookahead assertion) 
     .   # Match any character 
    )*   # Repeat as necessary 
    )   # End of capturing group 3 
    <else>  # Match <else> 
    (   # Same construction as above, group 4 
    (?: 
     (?! 
     </endif> # this time only looking for </endif> 
    ) 
     . 
    )* 
    ) 
    </endif>  # and finally match </endif> 
    %esix' 

두 번째 정규식도 개선되어야한다 : 그들은 더 명확하게 지정으로

'%<if:\s*"\'  # Match <if:(optional space)"\' 
    ([^\']*)  # Match 0 or more non-quote characters, capture group 1 
    \'\s==\s\' # Match \' == \' 
    ([^\']*)  # Match 0 or more non-quote characters, capture group 2 
    \'">   # Match \'"> 
    (   # Capture into group 3: 
    (?: 
     (?! 
     </endif> # Any text until </endif> 
    ) 
     . 
    )* 
    ) 
    </endif>  # and finally match </endif> 
    %esix' 

는 또한 이러한 정규 표현식에 더 빨리해야한다 무엇을 할 수 있고 일치 할 수 없으므로 많은 역 추적을 피할 수 있습니다.

+0

도움과 설명을 보내 주셔서 감사합니다. Tim! 초기 ' MrJ

+0

물론, 나는 나의 대답을 편집했다. –

관련 문제