我很想在代码块中突出显示函数的用法。 例如,看下面的示例代码中的fwrite()实例:
一个简单的preg_replace,我可以突出显示该功能:
$sample = preg_replace("/fwrite\((.*)\)\;?/U", "<code>$0</code>", $sample);
但是,如果该函数包含嵌套的括号,它将变得更加棘手。
如果是代码示例,则为:
...那么正则表达式模式将不知道fwrite()函数内部的内容不是该函数的结束。
答案 0 :(得分:1)
在第二个示例中,它在第一个)
(括号)处停止,因为表达式上带有U
(不整洁)标志。因此,它不再是默认的匹配行为,而是“惰性”并且尽可能少地匹配。要解决此问题,只需删除U
标志。
然后,我们必须解决以下事实:您的第一个示例从比赛中排除了;
(分号)。这是因为您有?
量词,以惰性(尽可能少,包括零)的方式与前面的字符匹配0或1次。要在删除U
标志后获得此行为,我们必须添加第二个?
,然后将默认行为从贪婪翻转为懒惰。
将它们放在一起,您应该得到:
$sample = preg_replace("/fwrite\((.*)\)\;??/", "<code>$0</code>", $sample);
答案 1 :(得分:0)
解决方案:
1)计数打开和关闭:
function highlightcode($fn, $sample){
$fn = rtrim($fn, ")");
if(!$pos = $start = strpos($sample, $fn)) return($sample); //not found
$opens = 1; $pos += strlen($fn);
while($pos < strlen($sample)){
$char = substr($sample, $pos, 1);
$opens += ($char == "(" ? 1 : ( $char == ")" ? -1 : 0));
//echo "POS: $pos CHAR: $char OPENS: $opens<br />";
if($opens < 1){ $end = $pos; break; }
$pos++;
}
return(substr($sample, 0, $start) . "<code>" . substr($sample, $start, ($end - $start)) . "</code>" . substr($sample, $end));
}
echo highlightcode("eval()", $sample);
2)正则表达式:
function highlightcode($fn, $sample){
$fn = rtrim($fn, "()");
$pattern = '~' . $fn . '(?= ( \( (?: [^()]+ | (?1) )*+ \) ) )~x';
if(!preg_match_all($pattern, $sample, $matches)) return( $sample );
foreach($matches[1] as $m){
$find = "{$fn}{$m}";
$repl = "<code>{$find}</code>";
$sample = str_replace($find, $repl, $sample);
}
return( $sample );
}
echo highlightcode("eval()", $sample);