2020-12-17:【正規表示式工具】使用Python+Tkinter構建RegexTool工具SourceCode2.0

小仙女的小跟班_fairy發表於2020-12-17

附帶了幫助資訊的工具原始碼

# encoding:utf8
"""
__author__ : weilinlin
__file__   : RegexTool
__time__   : 2020-12-16
"""
from tkinter import *
from tkinter import messagebox, ttk
import re

root = Tk()
root.title("RegexTool")
root.resizable(0, 0)


def init():
    """
    構造GUI初始化頁面
    TODO: 長度最大匹配長度判斷邏輯尚未補充
    TODO: 常用正規表示式列表
    :return:
    """
    button00 = Button(root, width=12, text="( )", command=lambda: (
    text1.insert('insert', "()"), text4.delete("1.0", END), text4.insert("insert", "(re): 對正規表示式分組並記住匹配的文字")))
    button01 = Button(root, width=12, text="[ ]", command=lambda: (
    text1.insert('insert', "[]"), text4.delete("1.0", END), text4.insert("insert", "[...]: 用來表示一組字元,單獨列出:[amk] 匹配 'a','m'或'k'")))
    button02 = Button(root, width=12, text="{ }", command=lambda: (text1.insert('insert', "{}"), text4.delete("1.0", END),
                                                                   text4.insert("insert",
                                                                                """re{ n}: 精確匹配 n 個前面表示式。例如, o{2} 不能匹配 "Bob" 中的 "o",但是能匹配 "food" 中的兩個 o。\nre{ n,}	匹配 n 個前面表示式。例如, o{2,} 不能匹配"Bob"中的"o",但能匹配 "foooood"中的所有 o。"o{1,}" 等價於 "o+"。"o{0,}" 則等價於 "o*"。""")))
    # button03 = Button(root, width=12, text="( )", command=lambda: text1.insert('insert', "()"))
    # button04 = Button(root, width=12, text="( )", command=lambda: text1.insert('insert', "()"))
    label03 = Label(root, width=12, text="長度")
    button04 = Button(root, width=12, text="{1, 15}", command=lambda: (
    text1.insert('insert', "{1,15}"), text4.delete("1.0", END), text4.insert("insert", "re{ n, m}	匹配 n 到 m 次由前面的正規表示式定義的片段,貪婪方式")))

    button10 = Button(root, width=12, text="*",
                      command=lambda: (text1.insert('insert', "*"), text4.delete("1.0", END), text4.insert("insert", "匹配0個或多個的表示式。")))
    button11 = Button(root, width=12, text="+",
                      command=lambda: (text1.insert('insert', "+"), text4.delete("1.0", END), text4.insert("insert", "匹配1個或多個的表示式。")))
    button12 = Button(root, width=12, text="?", command=lambda: (
    text1.insert('insert', "?"), text4.delete("1.0", END), text4.insert("insert", "匹配0個或1個由前面的正規表示式定義的片段,非貪婪方式。")))
    button13 = Button(root, width=12, text=".", command=lambda: (
    text1.insert('insert', "."), text4.delete("1.0", END), text4.insert("insert", "匹配任意字元,除了換行符,當re.DOTALL標記被指定時,則可以匹配包括換行符的任意字元。")))
    button14 = Button(root, width=12, text="-", command=lambda: (text1.insert('insert', "-"), text4.delete("1.0", END),
                                                                 text4.insert("insert",
                                                                              "標識兩者之間的內容也可以被匹配,連線作用;如[0-9],匹配可以匹配0,1,2,3,4,5,6,7,8,9。")))

    button20 = Button(root, width=12, text="0-9", command=lambda: (
    text1.insert('insert', "0-9"), text4.delete("1.0", END), text4.insert("insert", "匹配任何數字。類似於 [0123456789]")))
    button21 = Button(root, width=12, text="a-z", command=lambda: (
    text1.insert('insert', "a-z"), text4.delete("1.0", END), text4.insert("insert", "匹配任何小寫字母。類似於 [0123456789]")))
    button22 = Button(root, width=12, text="A-Z", command=lambda: (
    text1.insert('insert', "A-Z"), text4.delete("1.0", END), text4.insert("insert", "匹配任何大寫字母。類似於 [0123456789]")))
    button23 = Button(root, width=12, text="^",
                      command=lambda: (text1.insert('insert', "^"), text4.delete("1.0", END), text4.insert("insert", "匹配字串的開頭")))
    button24 = Button(root, width=12, text="$",
                      command=lambda: (text1.insert('insert', "$"), text4.delete("1.0", END), text4.insert("insert", "匹配字串的末尾")))

    button30 = Button(root, width=12, text="\w", command=lambda: (
    text1.insert('insert', "\w"), text4.delete("1.0", END), text4.insert("insert", "匹配包括下劃線的任何單詞字元。等價於'[A-Za-z0-9_]'。")))
    button31 = Button(root, width=12, text="\W", command=lambda: (
    text1.insert('insert', "\W"), text4.delete("1.0", END), text4.insert("insert", "匹配任何非單詞字元。等價於 '[^A-Za-z0-9_]'。")))
    button32 = Button(root, width=12, text="\d", command=lambda: (
    text1.insert('insert', "\d"), text4.delete("1.0", END), text4.insert("insert", "匹配一個數字字元。等價於 [0-9]。")))
    button33 = Button(root, width=12, text="\D", command=lambda: (
    text1.insert('insert', "\D"), text4.delete("1.0", END), text4.insert("insert", "匹配一個非數字字元。等價於 [^0-9]。")))
    button34 = Button(root, width=12, text="\\r",
                      command=lambda: (text1.insert('insert', "\\r"), text2.insert("insert", 'text2插入內容函式也可執行')))

    button40 = Button(root, width=12, text="\\b", command=lambda: (text1.insert('insert', "\\b"), text4.delete("1.0", END),
                                                                   text4.insert("insert",
                                                                                """匹配一個單詞邊界,也就是指單詞和空格間的位置。例如,'er\b' 可以匹配"never"中的 'er',但不能匹配 "verb" 中的 'er'。""")))
    button41 = Button(root, width=12, text="\B", command=lambda: (text1.insert('insert', "\B"), text4.delete("1.0", END),
                                                                  text4.insert("insert",
                                                                               """匹配非單詞邊界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。""")))
    button42 = Button(root, width=12, text="\\s", command=lambda: (
    text1.insert('insert', "\s"), text4.delete("1.0", END), text4.insert("insert", "匹配任意空白字元,等價於 [ \\t\\n\\r\\f]。")))
    button43 = Button(root, width=12, text="\S",
                      command=lambda: (text1.insert('insert', "\S"), text4.delete("1.0", END), text4.insert("insert", "匹配任意非空字元")))
    button44 = Button(root, width=12, text="\\n", command=lambda: (
    text1.insert('insert', "\\n"), text4.delete("1.0", END), text4.insert("insert", "匹配一個換行符。匹配一個製表符。等")))

    button50 = Button(root, width=12, text="\\u4e00-\\u9fa5", command=lambda: (
    text1.insert('insert', "\\u4e00-\\u9fa5"), text4.delete("1.0", END), text4.insert("insert", "匹配中文")))
    button51 = Button(root, width=12, text="|", command=lambda: (
    text1.insert('insert', "|"), text4.delete("1.0", END), text4.insert("insert", "a| b	匹配a或b")))
    button52 = Button(root, width=12, text="\\",
                      command=lambda: (text1.insert('insert', "\\"), text4.delete("1.0", END), text4.insert("insert", "轉義符")))
    button53 = Button(root, width=12, text="\\v", command=lambda: (text1.insert('insert', "\\v"), text4.delete("1.0", END),
                                                                   text4.insert("insert",
                                                                                "匹配任何空白字元,包括空格、製表符、換頁符等等。等價於 [ \\f\\n\\r\\t\\s]。")))
    button54 = Button(root, width=12, text="\\t", command=lambda: (text1.insert('insert', "\\t"), text4.delete("1.0", END),
                                                                   text4.insert("insert",
                                                                                "匹配任何空白字元,包括空格、製表符、換頁符等等。等價於 [ \\f\\n\\r\\v\\s]。")))

    button60 = Button(root, width=12, text="\\f", command=lambda: (text1.insert('insert', "\\f"), text4.delete("1.0", END),
                                                                   text4.insert("insert",
                                                                                "匹配任何空白字元,包括空格、製表符、換頁符等等。等價於 [ \\t\\n\\r\\v\\s]。")))
    label61 = Label(root, width=12, text="常用正規表示式")
    # 顯示可選值列表,另外處理
    button63 = Button(root, width=12, text="測試", command=checkRegex)
    button64 = Button(root, width=12, text="清空", command=clearAll)

    button00.grid(row=0, column=0, padx=5, pady=5)
    button01.grid(row=0, column=1, padx=5, pady=5)
    button02.grid(row=0, column=2, padx=5, pady=5)
    label03.grid(row=0, column=3, padx=5, pady=5)
    button04.grid(row=0, column=4, padx=5, pady=5)
    button10.grid(row=1, column=0, padx=5, pady=5)
    button11.grid(row=1, column=1, padx=5, pady=5)
    button12.grid(row=1, column=2, padx=5, pady=5)
    button13.grid(row=1, column=3, padx=5, pady=5)
    button14.grid(row=1, column=4, padx=5, pady=5)
    button20.grid(row=2, column=0, padx=5, pady=5)
    button21.grid(row=2, column=1, padx=5, pady=5)
    button22.grid(row=2, column=2, padx=5, pady=5)
    button23.grid(row=2, column=3, padx=5, pady=5)
    button24.grid(row=2, column=4, padx=5, pady=5)
    button30.grid(row=3, column=0, padx=5, pady=5)
    button31.grid(row=3, column=1, padx=5, pady=5)
    button32.grid(row=3, column=2, padx=5, pady=5)
    button33.grid(row=3, column=3, padx=5, pady=5)
    button34.grid(row=3, column=4, padx=5, pady=5)
    button40.grid(row=4, column=0, padx=5, pady=5)
    button41.grid(row=4, column=1, padx=5, pady=5)
    button42.grid(row=4, column=2, padx=5, pady=5)
    button43.grid(row=4, column=3, padx=5, pady=5)
    button44.grid(row=4, column=4, padx=5, pady=5)
    button50.grid(row=5, column=0, padx=5, pady=5)
    button51.grid(row=5, column=1, padx=5, pady=5)
    button52.grid(row=5, column=2, padx=5, pady=5)
    button53.grid(row=5, column=3, padx=5, pady=5)
    button54.grid(row=5, column=4, padx=5, pady=5)
    button60.grid(row=6, column=0, padx=5, pady=5)
    label61.grid(row=6, column=1, padx=5, pady=5)
    # 特殊處理可選值列表
    # label62.grid(row=6, column=2, padx=5, pady=5)
    button63.grid(row=6, column=3, padx=5, pady=5)
    button64.grid(row=6, column=4, padx=5, pady=5)


def clearAll():
    """
    清空三個text框,方便下次輸入表示式進行匹配計算
    :return:
    """
    text1.delete('1.0', 'end')
    text2.delete('1.0', 'end')
    text3.delete('1.0', 'end')
    text4.delete("1.0", END)
    pass


def go(*args):  # 處理事件,*args表示可變引數
    value = comboxlist.get()
    if value == "網頁連結":
        text1.delete('1.0', END)
        text1.insert('insert', '[a-zA-Z]+://[^\s]*')
    if value == "電子郵件":
        text1.delete('1.0', END)
        text1.insert('insert', '[a-zA-Z]+@[a-zA-Z]+.[a-zA-Z]+')
    if value == "身份證號":
        text1.delete('1.0', END)
        text1.insert('insert', '\d{15}|\d{18}')
    if value == "郵政編碼":
        text1.delete('1.0', END)
        text1.insert('insert', '[1-9]\d{5}(?!\d)')
    if value == "數字":
        text1.delete('1.0', END)
        text1.insert('insert', '[0-9]*')
    if value == "字母":
        text1.delete('1.0', END)
        text1.insert('insert', '[A-Za-z]+')
    if value == "大寫字母":
        text1.delete('1.0', END)
        text1.insert('insert', '[A-Z]+')
    if value == "小寫字母":
        text1.delete('1.0', END)
        text1.insert('insert', '[a-z]+')
    if value == "中文":
        text1.delete('1.0', END)
        text1.insert('insert', '[\\u4e00-\\u9fa5]{0,}')
    if value == "密碼":
        text1.delete('1.0', END)
        text1.insert('insert', '[a-zA-Z]\w{5,17}')
    if value == "手機號碼":
        text1.delete('1.0', END)
        text1.insert('insert', '(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9]\d{8})')
    # print(comboxlist.get())  # 列印選中的值


def listBox():
    """
    構造下拉選框
    :param root:
    :return:
    """
    comboxlist["values"] = ('常用正則', '網頁連結', '電子郵件', '身份證號', '郵政編碼', '數字', '字母', '大寫字母', '小寫字母', '中文', '密碼', '手機號碼')
    comboxlist.current(0)  # 選擇第一個
    comboxlist.bind("<<ComboboxSelected>>", go)  # 繫結事件,(下拉選單框被選中時,繫結go()函式)
    comboxlist.grid(row=6, column=2, padx=5, pady=5)
    pass


def checkRegex():
    """
    根據傳入的正規表示式和字串,輸出匹配結果
    :return:
    """
    text3.delete('1.0', 'end')  # 重新開始時,清空原有結果文字框中的所有內容
    var01 = text1.get('1.0', '1.end')  # 獲取正規表示式文字框中的內容,一行顯示
    var02 = text2.get('1.0', END)  # 獲取傳遞文字框中的所有內容,可以多行
    print("var01", var01)
    try:
        pattern = re.compile('%s' % var01)  # 根據傳入的正規表示式字串,生成正規表示式
        print(pattern)
        result = re.findall(pattern, var02)  # 呼叫re模組實現正則匹配
        if result:
            print(result)
            # 如果匹配結果不為空,那麼迴圈輸出正則匹配結果
            for res in result:
                if res != '':
                    text3.insert(END, res + '\n')
        else:  # 如果匹配失敗,在結果框中顯示提示資訊
            text3.delete('1.0', 'end')
            text3.insert('insert', '正則匹配結果為空')
    except:
        text3.delete('1.0', 'end')
        text3.insert('insert', '匹配失敗')


init()  # 初始化視窗

comvalue = StringVar()  # 窗體自帶的文字,新建一個值
comboxlist = ttk.Combobox(root, width=12, textvariable=comvalue)  # 初始化
listBox()  # 構建下拉選單,顯示常用正規表示式

label1 = Label(root, text="正規表示式", font=('黑體', 13))
label2 = Label(root, text="目標字串", font=('黑體', 13))
label3 = Label(root, text="匹配結果", font=('黑體', 13))
label4 = Label(root, text="幫助資訊", font=('黑體', 13))
text1 = Text(root, width=40, height=5, font=('黑體', 13))
text2 = Text(root, width=40, height=5, font=('黑體', 13))
text3 = Text(root, width=40, height=5, font=('黑體', 13))
text4 = Text(root, width=40, height=4, font=('黑體', 13))

label1.grid(row=7, column=0)
text1.grid(row=8, columnspan=6, pady=10)
label2.grid(row=9, column=0)
text2.grid(row=10, columnspan=6, pady=10)
label3.grid(row=11, column=0)
text3.grid(row=12, columnspan=6, pady=10)
label4.grid(row=13, column=0)
text4.grid(row=14, columnspan=6, pady=15)
root.mainloop()

相關文章