匹配 Tkinter 文本标签到字符串?

Match Tkinter Text tag to string?

我想知道是否可以将标签(例如 'keyword')绑定到字符串(例如 'print')到我在 Tkinter 中的 Text 小部件(Python).

我想知道这个,因为我不确定如何使用正则表达式连接到我的文本小部件,而且它看起来非常复杂,所以我想知道是否有任何正常的方法。


我当前的代码(SyntaxHighlighting.py):

global lang
lang = 'py'

def highlighter_bind(obj):
    # Bind a highlighting language to a text widget within obj.
    # Notice that obj must be a Frame with a .root property being
    # the root it is binded to, and a .text widget being where I
    # can highlight the text.
    #
    # The lang variable must be specified as a string that
    # contains the file extension of whatever you want to
    # highlight.
    #
    # Supported languages:
    #  - py

    def command(self):
        # Sub command for highlighting, it's what will
        # be "binded" to <Key>.

        if lang == 'py':
            print 'imported language py'

            # This is to get all the contents from the Text widget (property).
            t = o.text.get('1.0', END).split('\n')[0:len(o.text.get('1.0', END).split('\n')) - 1]

            # Now loop through the text and find + add a tag to each of the line's contents, assuming that there is something to be found.
            for i in range(0, len(t)):
                # We use the try / except because search.group will return an error if it's a NoneType.
                try:
                    # Now we need to search through the line and see if we can find print.
                    if search('print ', t[i]).group(0):
                        # Now, WHERE did we find print? I get confused there,
                        # because I have no idea where to find the index(es) of
                        # the string I found within a line. I use a regex to find the
                        # string, but how do I find where?
                        print "Ok!" # Temporary, just stating that I found it. It works.
                except:
                    pass
        else:
            print 'unrecognized language:', lang

   o.root.bind('<Key>', command)

实际工作的理想代码:

...
def command(self):
    if lang == 'py':
        obj.text.tag_match("print", 'keyword')
        # And even better, using regex to match..
        obj.text.tag_match("(if|elif|else)", 'keyword')
        obj.text.tag_match("(not|and|or)", 'keyword')
        obj.text.tag_match("(\+|-|*|/|**|%%)", 'keyword') # %% is to put a modulus in.

根据正则表达式或固定字符串应用高亮的方法是使用文本小部件search方法。您搜索原始文本然后尝试确定索引的方法不是正确的方法。

这是将标签 "keyword" 应用到词 "print" 的所有实例的示例:

import Tkinter as tk

class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.text = tk.Text(self, wrap="none")
        xsb = tk.Scrollbar(self, orient="horizontal", command=self.text.xview)
        ysb = tk.Scrollbar(self, orient="vertical", command=self.text.yview)
        self.text.configure(yscrollcommand=ysb.set, xscrollcommand=xsb.set)
        ysb.grid(row=0, column=1, sticky="ns")
        xsb.grid(row=1, column=0, sticky="ew")
        self.text.grid(row=0, column=0, sticky="nsew")
        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(0, weight=1)

        self.text.tag_configure("keyword", foreground="#b22222")

        # this probably isn't what you want to do in production, 
        # but it's good enough for illustrative purposes
        self.text.bind("<Any-KeyRelease>", self.highlight)
        self.text.bind("<Any-ButtonRelease>", self.highlight)

    def highlight(self, event=None):
        self.text.tag_remove("keyword", "1.0", "end")

        count = tk.IntVar()
        self.text.mark_set("matchStart", "1.0")
        self.text.mark_set("matchEnd", "1.0")

        while True:
            index = self.text.search("print", "matchEnd","end", count=count)
            if index == "": break # no match was found

            self.text.mark_set("matchStart", index)
            self.text.mark_set("matchEnd", "%s+%sc" % (index, count.get()))
            self.text.tag_add("keyword", "matchStart", "matchEnd")

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(fill="both", expand=True)
    root.mainloop()

有关将文本小部件子类化并添加用于突出显示任何正则表达式的方法的示例,请参阅 this answer to the question How to highlight text in a tkinter Text widget