문제

현재 PHP와 정규 표현식을 사용하여 페이지에서 모든 HTML 댓글을 제거하고 있습니다. 스크립트는 잘 작동합니다 ... 조금 잘 작동합니다. 그것은 내 조건부 의견을 포함하여 모든 의견을 제거합니다. 내가 가진 것들은 다음과 같습니다.

<?php
  function callback($buffer)
  {
        return preg_replace('/<!--(.|\s)*?-->/', '', $buffer);
  }

  ob_start("callback");
?>
... HTML source goes here ...
<?php ob_end_flush(); ?>

내 regex가 너무 뜨겁지 않기 때문에 다음과 같은 조건부 의견을 배제하기 위해 패턴을 수정하는 방법을 알아내는 데 어려움을 겪고 있습니다.

<!--[if !IE]><!-->
<link rel="stylesheet" href="/css/screen.css" type="text/css" media="screen" />
<!-- <![endif]-->

<!--[if IE 7]>
<link rel="stylesheet" href="/css/ie7.css" type="text/css" media="screen" />
<![endif]-->

<!--[if IE 6]>
<link rel="stylesheet" href="/css/ie6.css" type="text/css" media="screen" />
<![endif]-->

건배

도움이 되었습니까?

해결책

댓글은 HTML에 중첩 될 수 없으므로 이론적으로 동정인은 작업을 수행 할 수 있습니다. 그럼에도 불구하고, 어떤 종류의 파서를 사용하는 것이 더 나은 선택이 될 것입니다. 특히 입력이 잘 구성되지 않은 경우.

여기 내 시도가 있습니다. 정상적인 의견 만 일치시키기 위해서는 효과가 있습니다. 그것은 꽤 괴물이되었습니다. 죄송합니다. 나는 그것을 매우 광범위하게 테스트했지만 잘하는 것처럼 보이지만 보증은 제공하지 않습니다.

<!--(?!\s*(?:\[if [^\]]+]|<!|>))(?:(?!-->).)*-->

설명:

<!--                #01: "<!--"
(?!                 #02: look-ahead: a position not followed by:
  \s*               #03:   any number of space
  (?:               #04:   non-capturing group, any of:
    \[if [^\]]+]    #05:     "[if ...]"
    |<!             #06:     or "<!"
    |>              #07:     or ">"
  )                 #08:   end non-capturing group
)                   #09: end look-ahead
(?:                 #10: non-capturing group:
  (?!-->)           #11:   a position not followed by "-->"
  .                 #12:   eat the following char, it's part of the comment
)*                  #13: end non-capturing group, repeat
-->                 #14: "-->"

#02와 #11 단계가 중요합니다. #02는 다음 문자가 조건부 주석을 나타내지 않도록합니다. 그 후, #11은 다음 문자가 주석의 끝을 나타내지 않도록하고, #12와 #13은 실제 일치를 원합니다.

"Global"및 "DotAll"플래그를 적용하십시오.

반대 (조건부 의견 만 일치)를 수행하려면 다음과 같습니다.

<!(--)?(?=\[)(?:(?!<!\[endif\]\1>).)*<!\[endif\]\1>

설명:

<!                  #01: "<!"
(--)?               #02: two dashes, optional
(?=\[)              #03: a position followed by "["
(?:                 #04: non-capturing group:
  (?!               #05:   a position not followed by
    <!\[endif\]\1>  #06:     "<![endif]>" or "<![endif]-->" (depends on #02)
  )                 #07:   end of look-ahead
  .                 #08:   eat the following char, it's part of the comment
)*                  #09: end of non-capturing group, repeat
<!\[endif\]\1>      #10: "<![endif]>" or "<![endif]-->" (depends on #02)

다시, "글로벌"및 "dotall"플래그를 적용하십시오.

단계 #02는 "다운 레벨 리베일드"구문 때문입니다. "MSDN- 조건부 의견에 대해".

나는 공간이 허용되거나 예상되는 곳을 완전히 확신하지 못한다. 추가하다 \s* 적절한 표현에.

다른 팁

하나의 정규 표현으로 작업 할 수 없거나 사용할 수있는 더 많은 의견을 보존하려는 경우 preg_replace_callback. 그런 다음 주석을 개별적으로 처리 할 함수를 정의 할 수 있습니다.

<?php
function callback($buffer) {
    return preg_replace_callback('/<!--.*-->/U', 'comment_replace_func', $buffer);
}

function comment_replace_func($m) {
    if (preg_match( '/^\<\!--\[if \!/i', $m[0])) {
        return $m[0];   
    }              

    return '';
}   

ob_start("callback");
?>

... HTML source goes here ...

<?php ob_end_flush(); ?>

요약하면 이것은 최상의 솔루션 인 것 같습니다.

<?php
  function callback($buffer) {
    return preg_replace('/<!--[^\[](.|\s)*?-->/', '', $buffer);
  }
  ob_start("callback");
?>
... HTML source goes here ...
<?php ob_end_flush(); ?>

그것은 모든 의견을 제거하고 맨 위를 제외하고 조건부를 떠납니다.

<!--[if !IE]><!-->
<link rel="stylesheet" href="/css/screen.css" type="text/css" media="screen" />
<!-- <![endif]-->

추가로 문제가 발생하는 것 같습니다.

누구든지 이것을 고려하고 그 신분을 제자리에 두는 정규식을 제안 할 수 있다면 그것은 완벽 할 것입니다.

Tomalak의 솔루션은 좋아 보이지만 초보자와 더 이상 지침이없는 사람은 누구나 적용하는 방법에 대해 자세히 설명 할 수 있다면 시도해보고 싶지만 구현 방법을 모르겠습니까?

감사

PHP의 Regex 엔진이 다음과 같은 것을 좋아할지 확실하지 않지만이 패턴을 시도해보십시오.

'/<!--(.|\s)*(\[if .*\]){0}(.|\s)*?-->/'

이와 같은 것이 효과가있을 수 있습니다.

/<!--[^\[](.|\s)*?-->/

주석 시작 태그 직후에 주석이 오프닝 브래킷을 가지고 있다는 것을 제외하고는 당신과 동일합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top