簡體   English   中英

從已編譯的正則表達式 object 中獲取組子模式

[英]Get group subpatterns from a compiled regex object

我正在嘗試在正則表達式字符串中識別實際的“組中使用的正則表達式”,例如:

([A-Z]) (([OLUNCST]{1,2}=[a-zA-Z0-9-. ,]*){1,}\\s*C=[A-Z]{2})

我想要一種方法來提取組並得到這個:

Group 1: ([A-Z])

Group 2: (([OLUNCST]{1,2}=[a-zA-Z0-9-. ,]*){1,}\\s*C=[A-Z]{2})

Group 3: ([OLUNCST]{1,2}=[a-zA-Z0-9-. ,]*)

我試過使用 re.compile; 這給了我上面的組數(3)沒關系,這是我想知道的事情之一; 但我正在尋找的是每個搜索組的實際文本。

我從兩個方面看到這一點:

  1. 或者來自 're' lib 或 'sre_parse' lib(我已經看過)的內置方法來獲取此信息,或任何其他有用的庫
  2. 或者創建一個實際的正則表達式來分析正則表達式字符串...

現在我真正想要的是將組數(不改變實際的正則表達式)減少到 1,這樣我就可以務實地識別所有組並“刪除”它們周圍的括號,直到我離開最后一個(我只需要一個組在每個 re 表達式上)

現在我需要這個的原因:

我有一個像解析器一樣工作的程序,這個程序有一個龐大的“正則表達式”列表來嘗試一個字符串。

因此,不是循環遍歷讓我們說 10 個正則表達式來嘗試每一行日志(直到其中一個匹配),我所做的是將列表中的所有正則表達式加入到用“|”分隔的單行中並使用 re.findall,這個的好處是它會給我一個列表,使用所有連接的正則表達式找到的所有匹配項; 所以這個列表有效地代表了連接正則表達式的“匹配組”; 在列表中的每個正則表達式上使用單個組; 所以任何正則匹配(從正則表達式列表中只有一個正則表達式將匹配),組號匹配將是我將用來從該列表中獲取我需要使用的完整正則表達式的索引,並將其與該行一起使用。 這將消除對整個正則表達式列表的循環使用。

我使用的另一種方法只是一次“刪除”所有組,這在我發現這樣做會破壞某些特定的正則表達式之前效果很好:

在我的例子中,這個正則表達式:

([A-Z]) (([OLUNCST]{1,2}=[a-zA-Z0-9-. ,]*){1,}\s*C=[A-Z]{2})

會變成:

[A-Z] [OLUNCST]{1,2}=[a-zA-Z0-9-. ,]*{1,}\s*C=[A-Z]{2}
                                    ^^^^^
and this is an invalid regex--------^

我無法阻止這種情況,因為正則表達式將來可能會發生變化,並且手動搜索此類問題會很痛苦......

因此,如果我隔離每個組,我可以運行編譯來驗證帶有和不帶有括號的組,並決定是否將其取出,所以在我的情況下,我將與 3 個組交互:

Group 1: ([A-Z])

Group 2: (([OLUNCST]{1,2}=[a-zA-Z0-9-. ,]*){1,}\\s*C=[A-Z]{2})

Group 3: ([OLUNCST]{1,2}=[a-zA-Z0-9-. ,]*)

從第 1 組中取出括號-> 在沒有該組的情況下測試整個正則表達式(確定)

從第 2 組中取出括號 --> 在沒有該組的情況下測試整個正則表達式(確定)

從第 3 組中取出括號 --> 在沒有該組的情況下測試整個正則表達式(無效的 re 表達式) --> 不理會它。

這種方法還可以幫助我識別其他無法將其留在單個組中的正則表達式......我可以處理這些。

實際上,不需要第三次交互,就像最后一組一樣,這就是我需要的……整個表達式中的單個組。

任何人都可以提出一種實現這一目標的好方法嗎?

問候,

好的,在花費大量時間嘗試為正則表達式創建解析器以正確識別組以達到我想要的目的之后......我已經停止這樣做並重新思考......

我所做的是,使用正則表達式列表; 使用 re.compile 掃描每個正則表達式; 計算組數,然后創建一個輔助列表(這將在我的程序的初始化例程中,因為此信息將是靜態的),其中將包含包含該組的實際正則表達式的索引。 例如以下列表:

string = [
    "([A-Z]) (([OLUNCST]{1,2}=[a-zA-Z0-9-. ,]*){1,}\\s*C=[A-Z]{2})",
    "Received a notarisation request for Tx\\[([A-Z0-9]{64})\\] from \\[(([OLUNCST]{1,2}=[a-zA-Z0-9-. ,]*){1,}\\s*C=[A-Z]{2})\\]",
    "(Flow \\[([a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9-]{12})\\] error allowed to propagate)"
]

運行新代碼我得到了這個 output:

{0: {'groups': [1, 2, 3]}, 1: {'groups': [4, 5, 6]}, 2: {'groups': [7, 8]}}
[0, 0, 0, 1, 1, 1, 2, 2]

它的作用是模仿組計數,就好像它們是單個正則表達式的一部分一樣……這也給了我一個驗證點,我可以在其中管理要加入的正則表達式的數量……因為有時它可能會引起麻煩。

輔助列表的實際索引表示匹配組,該索引上的列表內容表示包含該組的實際正則表達式的索引列表......(字典僅用於測試和參考)

這意味着例如string列表上的正則表達式 1 正在使用第 5 組,這解決了我最初的擔憂。 而這個程序現在比以前運行得更快......

由於 re.compile 組總是從1開始,我還調整了我的程序的組數,但 python 列表從0開始; 所以我也考慮到了這一點

對於任何對我如何修復感興趣的人; 見下面的代碼:

import re
string = [
    "([A-Z]) (([OLUNCST]{1,2}=[a-zA-Z0-9-. ,]*){1,}\\s*C=[A-Z]{2})",
    "Received a notarisation request for Tx\\[([A-Z0-9]{64})\\] from \\[(([OLUNCST]{1,2}=[a-zA-Z0-9-. ,]*){1,}\\s*C=[A-Z]{2})\\]",
    "(Flow \\[([a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9-]{12})\\] error allowed to propagate)"
]

def group_index_reference(string_list):
    group_data = {}
    index_grp = []
    group_pos = 0
    for index, each_string in enumerate(string_list, start=0):
        rexp = re.compile(each_string)
        no_groups = rexp.groups
        group_data[index] = {
            "groups": [grp+group_pos for grp in range(1, no_groups + 1)]
        }
        for grp_no in range(group_pos, group_pos + no_groups):
            index_grp.append(index)
        group_pos += no_groups

    print(group_data)
    print(index_grp)

    return index_grp


group_index_reference(string)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM