这是tfpf 答案的扩展。
当您调用时,ic.make_pat()它会返回整个正则表达式以进行 python 格式化。OR尽管在某些额外的表达式中,从一侧或另一侧来看,它似乎很方便,但它并没有真正给您太多的控制权,而且很快就会变得很麻烦。一种可能更有用且绝对更可定制的方法是 print/copy/paste ic.make_pat(),并将其分解,如下所示。这还有一个额外的副作用,即您不必担心如何调用python 版本,因为在执行此操作之后,您根本ic.make_pat()不会使用。ic.make_pat()
#syntax highlighter patterns
KEYWORD = r"\b(?P<KEYWORD>False|None|True|and|as|assert|async|await|break|class|continue|def|del|elif|else|except|finally|for|from|global|if|import|in|is|lambda|nonlocal|not|or|pass|raise|return|try|while|with|yield)\b"
EXCEPTION = r"([^.'\"\\#]\b|^)(?P<EXCEPTION>ArithmeticError|AssertionError|AttributeError|BaseException|BlockingIOError|BrokenPipeError|BufferError|BytesWarning|ChildProcessError|ConnectionAbortedError|ConnectionError|ConnectionRefusedError|ConnectionResetError|DeprecationWarning|EOFError|Ellipsis|EnvironmentError|Exception|FileExistsError|FileNotFoundError|FloatingPointError|FutureWarning|GeneratorExit|IOError|ImportError|ImportWarning|IndentationError|IndexError|InterruptedError|IsADirectoryError|KeyError|KeyboardInterrupt|LookupError|MemoryError|ModuleNotFoundError|NameError|NotADirectoryError|NotImplemented|NotImplementedError|OSError|OverflowError|PendingDeprecationWarning|PermissionError|ProcessLookupError|RecursionError|ReferenceError|ResourceWarning|RuntimeError|RuntimeWarning|StopAsyncIteration|StopIteration|SyntaxError|SyntaxWarning|SystemError|SystemExit|TabError|TimeoutError|TypeError|UnboundLocalError|UnicodeDecodeError|UnicodeEncodeError|UnicodeError|UnicodeTranslateError|UnicodeWarning|UserWarning|ValueError|Warning|WindowsError|ZeroDivisionError)\b"
BUILTIN = r"([^.'\"\\#]\b|^)(?P<BUILTIN>abs|all|any|ascii|bin|breakpoint|callable|chr|classmethod|compile|complex|copyright|credits|delattr|dir|divmod|enumerate|eval|exec|exit|filter|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|isinstance|issubclass|iter|len|license|locals|map|max|memoryview|min|next|oct|open|ord|pow|print|quit|range|repr|reversed|round|set|setattr|slice|sorted|staticmethod|sum|type|vars|zip)\b"
DOCSTRING = r"(?P<DOCSTRING>(?i:r|u|f|fr|rf|b|br|rb)?'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(''')?|(?i:r|u|f|fr|rf|b|br|rb)?\"\"\"[^\"\\]*((\\.|\"(?!\"\"))[^\"\\]*)*(\"\"\")?)"
STRING = r"(?P<STRING>(?i:r|u|f|fr|rf|b|br|rb)?'[^'\\\n]*(\\.[^'\\\n]*)*'?|(?i:r|u|f|fr|rf|b|br|rb)?\"[^\"\\\n]*(\\.[^\"\\\n]*)*\"?)"
TYPES = r"\b(?P<TYPES>bool|bytearray|bytes|dict|float|int|list|str|tuple|object)\b"
NUMBER = r"\b(?P<NUMBER>((0x|0b|0o|#)[\da-fA-F]+)|((\d*\.)?\d+))\b"
CLASSDEF = r"(?<=\bclass)[ \t]+(?P<CLASSDEF>\w+)[ \t]*[:\(]" #recolor of DEFINITION for class definitions
DECORATOR = r"(^[ \t]*(?P<DECORATOR>@[\w\d\.]+))"
INSTANCE = r"\b(?P<INSTANCE>super|self|cls)\b"
COMMENT = r"(?P<COMMENT>#[^\n]*)"
SYNC = r"(?P<SYNC>\n)"
Run Code Online (Sandbox Code Playgroud)
然后您可以按照适合您的顺序连接所有这些模式,如下所示:
PROG = rf"{KEYWORD}|{BUILTIN}|{EXCEPTION}|{TYPES}|{COMMENT}|{DOCSTRING}|{STRING}|{SYNC}|{INSTANCE}|{DECORATOR}|{NUMBER}|{CLASSDEF}"
Run Code Online (Sandbox Code Playgroud)
您可能会注意到DEFINITION上述任何模式中都不存在这一点。这是因为上面的模式是针对 的.prog,但是DEFINITION模式是由 确定的.idprog。下面是我的。我希望类定义具有不同的颜色,因此我的模式会忽略前面带有class. 如果您不打算做出一些例外,则DEFINITION根本不必打扰它。
#original - r"\s+(\w+)"
IDPROG = r"(?<!class)\s+(\w+)"
Run Code Online (Sandbox Code Playgroud)
接下来要考虑的是tagdefs。您无需逐行添加/修改键,只需预定义tagdefs. 下面是一个例子。请注意,regex group上面第一组模式中使用的每个名称都用下面对象中的键表示。另请注意,DEFINITION此处包含该内容。下面的每个对象都变为optionsfor tag_configure,您可以使用任何接受的option对象tag_configure。颜色和字体是我自己的,示例中不需要包含它们。
TAGDEFS = { 'COMMENT' : {'foreground': CHARBLUE , 'background': None},
'TYPES' : {'foreground': CLOUD2 , 'background': None},
'NUMBER' : {'foreground': LEMON , 'background': None},
'BUILTIN' : {'foreground': OVERCAST , 'background': None},
'STRING' : {'foreground': PUMPKIN , 'background': None},
'DOCSTRING' : {'foreground': STORMY , 'background': None},
'EXCEPTION' : {'foreground': CLOUD2 , 'background': None, 'font':FONTBOLD},
'DEFINITION' : {'foreground': SAILOR , 'background': None, 'font':FONTBOLD},
'DECORATOR' : {'foreground': CLOUD2 , 'background': None, 'font':FONTITAL},
'INSTANCE' : {'foreground': CLOUD , 'background': None, 'font':FONTITAL},
'KEYWORD' : {'foreground': DK_SEAFOAM, 'background': None, 'font':FONTBOLD},
'CLASSDEF' : {'foreground': PURPLE , 'background': None, 'font':FONTBOLD},
}
'''
#what literally happens to this data when it is applied
for tag, cfg in self.tagdefs.items():
self.tag_configure(tag, **cfg)
'''
Run Code Online (Sandbox Code Playgroud)
一旦完成该设置,您就可以轻松插入所有内容。如果您制作自定义文本小部件,您可以将以下内容放入__init__并更改YourTextWidget为self. 否则,只需更改YourTextWidget为您想要连接到的文本小部件的实例名称(如tfpf 的答案中所示)。
cd = ic.ColorDelegator()
cd.prog = re.compile(PROG, re.S|re.M)
cd.idprog = re.compile(IDPROG, re.S)
cd.tagdefs = {**cd.tagdefs, **TAGDEFS}
ip.Percolator(YourTextWidget).insertfilter(cd)
Run Code Online (Sandbox Code Playgroud)
cd.tagdefs = {**cd.tagdefs, **TAGDEFS}
我为什么要这样做?我们不会使用此方法省略任何值。KEYWORD如果定义在 中tagdefs,而不是在 中怎么办TAGDEFS?如果我们不首先将tagdefs自己解开,我们就会失败KEYWORD。
总结系统的这一端:运行一个大的正则表达式,任何regex group匹配的名称都会成为要应用的标签的名称。无论regex groups您创建什么新内容,都应该(也许必须)在.tagdefs.