Skip to main content
 首页 » 编程设计

python之突出显示一堆单词

2025年05月04日12zhujiabin

我试图突出显示一堆单词 - 所以我写了一个 pygments 扩展。基本上它有效,但仍然不令我满意。

这里有一个应该可行的简单想法:适本地突出显示单词,以及与这些单词不匹配的所有其他文本 - 在文本中。但这挂断了:

from pygments.lexer import RegexLexer 
from pygments.token import * 
 
class HotKeyPoetry(RegexLexer): 
    name = 'HotKeyPoetry' 
    aliases = ['HotKeyPoetry'] 
    filenames = ['*.hkp'] 
 
    tokens = { 
        'root': [ 
 
            (r'\bAlt\b', Generic.Traceback), 
            (r'\bShft\b', Name.Variable), 
            (r'\bSpc\b', Operator), 
            (r'\bCtrl\b', Keyword.Type), 
            (r'\bRet\b', Name.Label), 
            (r'\bBkSpc\b', Generic.Inserted), 
            (r'\bTab\b', Keyword.Type), 
            (r'\bCpsLk\b', String.Char), 
            (r'\bNmLk\b', Generic.Output), 
            (r'\bScrlLk\b', String.Double), 
            (r'\bPgUp\b', Name.Attribute), 
            (r'\bPgDwn\b', Name.Builtin), 
            (r'\bHome\b', Number.Oct), 
            (r'\bEnd\b', Name.Constant), 
            (r'\bDel\b', Name.Decorator), 
            (r'\bIns\b', Number.Integer.Long), 
            (r'\bWin\b', Name.Builtin.Pseudo), 
            (r'\bF1?[1-9]\b', Name.Function), 
 
            (r'(?!\b(Alt|Shft|Spc|Ctrl|Ret|BkSpc|Tab|CpsLk|NmLk|ScrlLk|PgUp|PgDwn|Home|End|Del|Ins|Win|F5)\b)', Text), 
 
        ] 
    } 

也许我应该更好地使用另一个词法分析器来完成这项工作?

编辑 1

所以

r"(.+?)(?:$|\b(?=(Alt|Shft|Spc|Ctrl|Ret|BkSpc|Tab|CpsLk|NmLk|ScrlLk|PgUp|P‌​gDwn|‌​Home|End|Del|Ins|Win|F[12]?[1-9])\b))" 

是我一直在寻找的排他性正则表达式。

现在我正在尝试使 # 成为注释字符——这样它后面的所有内容(在一行内)——都是注释:我试过:

r"(.+?)(?:$|#.*$|\b(?=(Alt|Shft|Spc|Ctrl|Ret|BkSpc|Tab|CpsLk|NmLk|ScrlLk|PgUp|P‌​gDwn|‌​Home|End|Del|Ins|Win|F[12]?[1-9])\b))" 

和

r"([^#]+?)(?:$|\b(?=(Alt|Shft|Spc|Ctrl|Ret|BkSpc|Tab|CpsLk|NmLk|ScrlLk|PgUp|PgD‌​wn|‌​Home|End|Del|Ins|Win|F[12]?[1-9])\b))" 

其次是

 (r'#.*$', Comment), 

我还尝试添加第二个状态:

'comment': [  
      (r'#.*$', Comment), 
], 

-- 但没有任何作用。

编辑2

完整的工作 pygments 扩展 python 包是 here .你可以得到和

python setup.py build 
python setup.py install --user 

它在 pygments 中注册它。然后您可以使用以下方法对其进行测试:

pygmentize -f html -O full -o test.html test.hkp 

或指定一种语言:

pygmentize -f html -O full -l HotKeyPoetry -o test.html test.hkp 

这是一个示例 test.hkp:

Ctrl-Alt-{Home/End} ⇒ {beginning/end}-of-visual-line 
Ctrl-Alt-{b/↓/↑} ⇒ {set/goto next/goto previous} bookmark # I have it in okular and emacs 
Alt-{o/O} ⇒ switch-to-buffer{/-other-window} 
Ctrl-{o/O} ⇒ find-file{/-other-window} 
Ctrl-x o ⇒ ergo-undo-close-buffer # it uses ergoemacs' recently-closed-buffers 
Ctrl-Alt-O ⇒ find-alternate-file 

(注释对于热键不是很有用——但我需要它们用于 PyMOL)。

请您参考如下方法:

1) 您误解了 (?! 的工作原理:它不匹配文本。您的最后一个 RE(在原始代码块中)在 位置 匹配后面没有您列出的任何单词。但它与文本的零个字符匹配,因此没有任何颜色可供选择,您也不会继续前进。

你真正的意思是这样的:\b(?!(?:Alt|Shft|etc)\b)\w+\b。 (匹配 \b 之间的任何单词 \w+,但如果第一个 \b 后跟任何关键字则不匹配)

2) 关于匹配注释:根据 pygments 文档,您的表达式 (r'#.*$', Comment) 应该有效。或者,在示例中使用的样式中:

(r'#.*\n', Comment), 

3) 你只需要一个状态,所以将评论规则添加到根状态。多个状态适用于在不同地方使用不同语法的情况,例如如果您混合使用 html 和 PHP,或者如果您想突出显示 python 字符串中的 SQL。

4) 您的规则需要匹配输入中的所有内容。规则会按顺序尝试,直到一个起作用为止,因此您可以将此通配符作为您的最后规则,而不是尝试编写与关键字不匹配的规则:

(r'(?s).', Text), 

它会一次推进一个字符,直到您获得其他规则可以匹配的内容。重复一遍:删除匹配非关键字的长规则,改用上面的规则。