2009-10-23 79 views
0

您好所有IM目前正在寫「顯示PHP代碼」功能(輸出可以在http://www.actwebdesigns.co.uk/web-design-mansfield/php-functions/display-code-function.php可見)的Preg匹配

與由正則表達式進行的顏色方案具有麻煩林。 尤其是2:

字符串:

$line = preg_replace("#(\s|\()(\"[^\"]*\")(\,|\))#is", "\\1<span class=\"string\">\\2</span>\\3", $line); 

(和試圖)

#\"((?!(?:\"\s*;)|(?:\"\s*,)).)*#is 

和功能:

$line = preg_replace("#(\s*)(@?|!?[a-z]+(?:[a-z]|[0-9]|_)*)(\s*)\(([^\)]*)\)#is", "\\1<span class=\"function\">\\2\\3</span>(\\4)", $line); 

(如果函數是一個函數在其內部不會改變顏色

+0

你自我完善這樣做還是你不知道'highlight_string()'? – 2009-10-23 08:29:50

回答

0

爲什麼這麼複雜?使用hightlight_string()。 ...和輸出緩衝和ini_set(),如果你需要改變它的輸出。

+0

似乎沒有做什麼之後...似乎並沒有突出功能等等,並輸出到處都是。 – 2009-10-23 07:13:35

0

關於您的字符串的正則表達式:你說這是一個字符串,當且僅當它是由一個空格字符或(之前 它直接後跟一個,)。 針說,那是不正確的。你會錯過像字符串:(?有更多的人,和什麼有關「這裏-文檔」)

$s = "123";  // ends with a ; 
$s = "ab\"cd"; // contains an escaped double quote 
$t = 'efg' ; // is surrounded by single quotes 

僅舉出三種。

爲了考慮解決的情況下上面,嘗試這樣的事情:

$line = 's = "123"; t = "ab\\\\\\"cd"; u = \'efg\' ; v = \'ef\\\'g\' '; 
echo $line . "\n"; 
echo preg_replace('/((["\'])(?:\\\\.|(?:(?!\2).|[^\\\\"\'\r\n]))*\2)/', '<span class="string">$1</span>', $line); 
/* output: 
s = "123"; t = "ab\\\"cd"; u = 'efg' ; v = 'ef\'g' 
s = <span class="string">"123"</span>; t = <span class="string">"ab\\\"cd"</span>; u = <span class="string">'efg'</span> ; v = <span class="string">'ef\'g'</span> 
*/ 

的簡短解釋:

(      # start group 1 
    (["\'])    # match a single- or double quote and store it in group 2 
    (?:     #  start non-matching group 1 
    \\\\.    #  match a double quote followed by any character (except line breaks) 
    |     #  OR 
    (?:     #  start non-matching group 2 
     (?!\2).   #  a character other than what is captured in group 2 
     |     #  OR 
     [^\\\\"\'\r\n]  #  any character except a backslash, double quote, single quote or line breaks 
    )     #  end non-matching group 2 
)*      # end non-matching group 1 and match it zero or more times 
    \2      # the quote captured in group 2 
)      # end group 1 

然後關於你的第二個正則表達式的一些評論:您第一次嘗試匹配零個或多個 空白字符。這可以安全地省略,因爲如果不存在空格 你仍然有一個匹配。在匹配 函數名稱之前,您可以使用\b(字邊界)。另外,(?:[a-z]|[0-9]|_)可以替換爲(?:[a-z0-9_])。而 這部分您正則表達式的:(@?|!?[a-z]+(?:[a-z]|[0-9]|_)*)這是一樣的:

(
    @? 
    | 
    !? 
    [a-z]+ 
    (?: 
    [a-z] 
    | 
    [0-9] 
    | 
    _ 
)* 
) 

只有更好縮進,看看它實際上做。如果仔細觀察,你會發現它只會匹配@?,並且由於?使得@成爲可選項,所以 部分的正則表達式也會匹配空字符串。沒有你期望的,呃?之後,我必須承認我已經停止了看那個正則表達式,最好把它扔掉。

嘗試這樣的事情來匹配函數名:

'/\b[a-z_][a-z0-9_]*(?=\s*\()/i' 

這意味着:

\b   # a word boundary (the space between \w and \W) 
[a-z_]  # a letter or an underscore 
[a-z0-9_]* # a letter, digit or an underscore, zero or more times 
(?=   # start positive look ahead 
    \s*  # zero ore more white space characters 
    \(  # an opening parenthesis 
)   # end positive look ahead 

這最後一個未測試的所有,我留給你。另外請注意,我知道PHP很少,所以我可能會過度簡化它,在這種情況下,如果您提供了一些您想要作爲函數匹配的示例代碼片段,這將有所幫助。

另外一個謹慎的話,使用正則表達式-ES可能會非常棘手解析代碼,但如果 你只使用它來執行代碼片段的高亮,你 應該罰款。當源文件變大時,您可能會看到 性能的下降,並且您應該使正則表達式中的某些部分( )會增加匹配的運行時(特別是在較大的源文件上)。

最後,您可能重新發明了方向盤。您可以使用許多(測試良好的)代碼熒光筆。我懷疑你已經知道這一點,但我認爲它仍然值得一提。

僅供參考,我有很好的經驗與這一個:http://shjs.sourceforge.net/doc/documentation.html