2013-08-25 32 views
2

我想提取此部分使用正則表達式的整個PHP代碼:提取PHP代碼使用正則表達式

<h1>Extract the PHP Code</h1> 
    <?php 
     echo(date("F j, Y, g:i a") . ' and a stumbling block: ?>'); 
     /* Another stumbling block ?> */ 
     echo(' that works.'); 
    ?> 
<p>Some HTML text ...</p> 

不幸的是,我的正則表達式陷絆腳石上:

/<[?]php[^?>]*[?]>/gim 

不有人有提示如何捕獲完整的PHP代碼?

+6

如果使用正則表達式,使用http://php.net/tokenizer。 – mario

回答

4

像這樣的東西可能會奏效

/<\?php.+?\?>$/ms 

Regular expression visualization

該模式使用了兩個flags

  • mPCRE_MULTILINE

    默認情況下,PCRE將主題字符串視爲由單個「行」字符組成(即使它實際上包含多個換行符)。 「起始行」元字符(^)僅匹配字符串的開頭,而「行尾」元字符($)僅匹配字符串末尾或終止換行符之前(除非D修改符被設置)。這與Perl相同。當這個修飾符被設置時,「起始行」和「行結束」構造分別緊跟在主題字符串中的任何換行符之後或之前,以及在最開始和結束時匹配。這相當於Perl的/m修飾符。如果主題字符串中沒有"\n"字符,或者模式中沒有出現^$,則設置此修飾符不起作用。

  • sPCRE_DOTALL

    如果設定了此修正,在模式中的圓點元字符的所有字符,包括換行符相匹配。沒有它,換行符被排除在外。這個修飾符相當於Perl的/s修飾符。否定類如[^a]總是與換行符匹配,與此修飾符的設置無關。

這裏的幾場比賽將是什麼樣子

enter image description here


買者,如果它不能在一行的末尾找到?>這是行不通的。

所以它的工作原理在

  • ?>');
  • ?> */

的情況下,但它不會對工作

<?php 
    echo "actual code"; 
    /* 
    * comment ?> 
    */ 
?> 

總而言之,如果你的代碼是凌亂,你需要一個更好的解決方案。如果你的代碼乾淨,它應該工作得很好。

+0

非常感謝你! – Max

3

你可以用這個模式嘗試:

$pattern = <<<'LOD' 
~ 

#definitions 
(?(DEFINE) 
    (?<sq> '(?>[^'\\]+|\\.)*+(?>'|\z)) # content inside simple quotes 
    (?<dq> "(?>[^"\\]+|\\.)*+(?>"|\z)) # content inside double quotes 
    (?<vn> [a-zA-Z_]\w*+) # variable name 
    (?<crlf> \r?\n) # CRLF 
    (?<hndoc> <<< (["']?) (\g<vn>) \g{-2} \g<crlf> # content inside here/nowdoc 
       (?> [^\r\n]+ | \R+ (?!\g{-1}; $))*+ 
       (?: \g<crlf> \g{-1}; \g<crlf> | \z) 
    ) 
    (?<cmt> /\*      # multiline comments 
      (?> [^*]+ | \* (?!/))*+ 
      \*/ 
    ) 
) 

#pattern 
<\?php \s+ 
(?> [^"'?/<]+ | \?+(?!>) | \g<sq> | \g<dq> | \g<hndoc> | \g<cmt> | [</]+)*+ 
(?: \?> | \z) 

~xsm 
LOD; 

測試:

$subject = <<<'LOD' 
<h1>Extract the PHP Code</h1> 
    <?php 
     echo(date("F j, Y, g:i a") . ' and a stumbling block: ?>'); 
     /* Another stumbling block ?> */ 
     echo <<<'EOD' 
    Youpi!!! ?> 
EOD; 
     echo(' that works.'); 
    ?> 
<p>Some HTML text ...</p> 
LOD; 

preg_match_all($pattern, $subject, $matches); 

print_r($matches); 


另一種方式:

馬里奧表明,它在一個評論,你可以使用標記生成器。這是最簡單的方法,因爲你不需要定義任何東西,例如:

$tokens = token_get_all($subject); 
$display = false; 
foreach ($tokens as $token) { 
    if (is_array($token)) { 
     if ($token[0]==T_OPEN_TAG) $display = true; 
     if ($display) echo $token[1]; 
     if ($token[0]==T_CLOSE_TAG) $display = false; 
    } else { 
     if ($display) echo $token; 
    } 
} 
+0

一個非常不錯的正則表達式* + 1 * – HamZa

+0

@ m.buettner:單行註釋不停止?>' –

+0

@CasimiretHippolyte啊,很高興知道 –