2009-10-02 4 views
6

한 줄 주석 (//...)을 회신하여 (/*...*/)을 (를) 차단해야합니다. 나는 다음 코드에서 거의 이것을 수행했다. 그러나 한 줄 주석을 건너 뛰는 함수가 이미 블록 주석에 있습니다. 현재 단일 행 주석이 블록 주석에있는 경우에도 모든 단일 행 주석과 일치합니다.단일 회선 주석을 차단하려면

## Convert Single Line Comment to Block Comments 
function singleLineComments(&$output) { 
    $output = preg_replace_callback('#//(.*)#m', 
    create_function(
    '$match', 
    'return "/* " . trim(mb_substr($match[1], 0)) . " */";' 
    ), $output 
); 
} 

답변

1

당신은 뒤에 부정적인 모습을 시도 할 수 :

## Convert Single Line Comment to Block Comments 
function sinlgeLineComments(&$output) { 
    $output = preg_replace_callback('#^((?:(?!/\*).)*?)//(.*)#m', 
    create_function(
    '$match', 
    'return "/* " . trim(mb_substr($match[1], 0)) . " */";' 
), $output 
); 
} 

http://www.regular-expressions.info/lookaround.html 그러나 나는 그들에 //와 가능한 문자열에 대해 우려하고있다. like : $ x = "some string // with slashes"; 변환 되나요?

소스 파일이 PHP 인 경우 tokenizer를 사용하여 파일을보다 정확하게 파싱 할 수 있습니다.

http://php.net/manual/en/tokenizer.examples.php

편집 : 는 식을 중첩함으로써 극복 할 수있는 고정 길이에 대해 잊어 버렸습니다. 위는 지금 작동해야합니다.

이미 언급했듯이
$foo = "// this is foo"; 
sinlgeLineComments($foo); 
echo $foo . "\n"; 

$foo2 = "/* something // this is foo2 */"; 
sinlgeLineComments($foo2); 
echo $foo2 . "\n"; 

$foo3 = "the quick brown fox"; 
sinlgeLineComments($foo3); 
echo $foo3. "\n";; 
+0

글쎄, $ x = "some strings // with slashes"라고 걱정하지 않아도됩니다. $ x = "슬래시가있는 일부 문자열/* /" "이됩니다. 그것은 실제로 선호 될 것입니다. 반면에, 나는 당신이 제안한 변경 사항을 추가하고 컴파일 오류가 발생했습니다. 경고 : preg_replace_callback() [function.preg-replace-callback] : 컴파일 실패 : lookbehind 어설 션이 C : \ Wamp \ www \ LessCSS \ Site \ cleaner \ inc \ util.php의 오프셋 6에서 고정 길이가 아닙니다. 29 – roydukkey

+1

PHP의 룩백 기능은 고정 길이 어설 션만을 지원합니다. 즉, * 및?의 사용을 배제하는 정의되지 않은 수의 문자와 일치하는 룩백 (look-behind) 정규 표현식을 작성할 수 없다는 것을 의미합니다. 더 많은 정보는 여기에 있습니다 : http://www.php.net/manual/en/regexp.reference.assertions.php –

+0

머리를 주셔서 감사합니다. 지금 일해야합니다. –

3

, "//...는"블록의 의견과 문자열 리터럴 내에서 발생할 수 있습니다 나는 그것을 테스트했습니다. 그래서 만약 당신이 약간의 regex-trickery를 사용하여 작은 "파서"를 만들면, 먼저 그 중 하나 (문자열 리터럴이나 블록 주석)와 일치 할 수 있고, 그 후에는 "//..."이 존재하는지 테스트 할 수 있습니다. 다음과 같은 출력을 생성

$code ='A 
B 
// okay! 
/* 
C 
D 
// ignore me E F G 
H 
*/ 
I 
// yes! 
K 
L = "foo // bar // string"; 
done // one more!'; 

$regex = '@ 
    ("(?:\\.|[^\r\n\\"])*+") # group 1: matches double quoted string literals 
    | 
    (/\*[\s\S]*?\*/)   # group 2: matches multi-line comment blocks 
    | 
    (//[^\r\n]*+)    # group 3: matches single line comments 
@x'; 

preg_match_all($regex, $code, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE); 

foreach($matches as $m) { 
    if(isset($m[3])) { 
    echo "replace the string '{$m[3][0]}' starting at offset: {$m[3][1]}\n"; 
    } 
} 

:

여기 작은 데모 과정의

replace the string '// okay!' starting at offset: 6 
replace the string '// yes!' starting at offset: 56 
replace the string '// one more!' starting at offset: 102 

, 나는 가정,이 PHP에서 가능한 많은 문자열 리터럴은,하지만 당신은 내 드리프트를 얻을.

HTH.

관련 문제