GeSHi语言文件开发:如何高亮关键字后的未知单词?
GeSHi高亮关键字后未知单词的解决方案
问题描述
我正在为GeSHi开发语言文件,希望高亮关键字及空白字符后的未知单词。尝试了如下代码:
$language_data = array ( ... 'KEYWORDS' => array( 1 => array( 'keyword1', 'keyword2' ) ), ... 'REGEXPS' => array( 0 => array( GESHI_SEARCH => '(((keyword1|keyword2)\s+)([a-zA-Z_][a-zA-Z0-9_]*))', GESHI_REPLACE => '\\4', GESHI_MODIFIERS => '', GESHI_BEFORE => '\\2', GESHI_AFTER => '' ) ), ... )
但该正则表达式始终无法匹配,推测正则测试时关键字已被解析器消耗。由于实际关键字及分隔空白的长度不固定,无法使用后行断言,请问如何实现?
解决方法
方法1:调整正则优先级,让正则先于关键字处理
GeSHi默认先解析关键字再处理正则,导致关键字被标记为HTML后正则无法匹配原始文本。可以通过给正则设置更高优先级,让它先执行:
- 从
KEYWORDS中移除目标关键字,避免重复处理 - 修改
REGEXPS配置,添加GESHI_PRIORITY参数并设为高于关键字的优先级,关键字默认优先级为0,设为1即可 - 在替换规则中同时给关键字和后续单词设置高亮样式
示例代码:
$language_data = array ( ... // 移除KEYWORDS中的keyword1、keyword2 'KEYWORDS' => array( // 保留其他关键字配置 ), ... 'REGEXPS' => array( 0 => array( GESHI_SEARCH => '((keyword1|keyword2)\s+)([a-zA-Z_][a-zA-Z0-9_]*)', // 分别给关键字和后续单词添加不同样式类 GESHI_REPLACE => '<span class="geshi-keyword">\\1</span><span class="geshi-target-word">\\3</span>', GESHI_MODIFIERS => '', GESHI_PRIORITY => 1 // 优先级高于关键字,先执行 ) ), ... );
方法2:使用自定义单词解析钩子(部分GeSHi版本支持)
如果你的GeSHi版本支持WORD_PARSER钩子,可以通过自定义函数判断单词上下文,实现高亮:
// 自定义单词解析钩子函数 function highlight_keyword_follow_word(&$word, &$line, &$parser) { // 获取当前单词之前的文本,检查是否以目标关键字加空白结尾 $prev_pos = $parser->current_pos - strlen($word); if ($prev_pos > 0) { $prev_text = substr($line, 0, $prev_pos); // 匹配关键字加任意空白字符结尾 if (preg_match('/(keyword1|keyword2)\s+$/', $prev_text)) { // 返回自定义样式类名,GeSHi会用这个类高亮当前单词 return 'geshi-target-word'; } } // 返回false表示不修改当前单词的高亮 return false; } $language_data = array ( ... 'KEYWORDS' => array( 1 => array( 'keyword1', 'keyword2' ) ), // 添加自定义单词解析钩子 'WORD_PARSER' => 'highlight_keyword_follow_word', ... );
这种方法可以保留KEYWORDS中的关键字配置,同时通过钩子识别关键字后的单词并高亮。
内容的提问来源于stack exchange,提问作者maf
相关产品推荐
相关产品推荐

