最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python如何使用組合方式構(gòu)建復(fù)雜正則

 更新時(shí)間:2024年12月02日 15:31:28   作者:韋易笑  
在Python中正則寫(xiě)復(fù)雜了很麻煩,難寫(xiě)難調(diào)試,其實(shí)只需要兩個(gè)函數(shù),就能用簡(jiǎn)單正則組合構(gòu)建復(fù)雜正則,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

正則寫(xiě)復(fù)雜了很麻煩,難寫(xiě)難調(diào)試,只需要兩個(gè)函數(shù),就能用簡(jiǎn)單正則組合構(gòu)建復(fù)雜正則:

比如輸入一個(gè)字符串規(guī)則,可以使用 {name} 引用前面定義的規(guī)則:

# rules definition
rules = r'''
    protocol = http|https
    login_name = [^:@\r\n\t ]+
    login_pass = [^@\r\n\t ]+
    login = {login_name}(:{login_pass})?
    host = [^:/@\r\n\t ]+
    port = \d+
    optional_port = (?:[:]{port})?
    path = /[^\r\n\t ]*
    url = {protocol}://({login}[@])?{host}{optional_port}{path}?
'''

然后調(diào)用 regex_build 函數(shù),將上面的規(guī)則轉(zhuǎn)換成一個(gè)字典并輸出:

# expand patterns in a dictionary
m = regex_build(rules, capture = True)

# list generated patterns
for k, v in m.items(): 
    print(k, '=', v)

結(jié)果:

protocol = (?P<protocol>http|https)
login_name = (?P<login_name>[^:@\r\n\t ]+)
login_pass = (?P<login_pass>[^@\r\n\t ]+)
login = (?P<login>(?P<login_name>[^:@\r\n\t ]+)(:(?P<login_pass>[^@\r\n\t ]+))?)
host = (?P<host>[^:/@\r\n\t ]+)
port = (?P<port>\d+)
optional_port = (?P<optional_port>(?:[:](?P<port>\d+))?)
path = (?P<path>/[^\r\n\t ]*)
url = (?P<url>(?P<protocol>http|https)://((?P<login>(?P<login_name>[^:@\r\n\t ]+)(:(?P<login_pass>[^@\r\n\t ]+))?)[@])?(?P<host>[^:/@\r\n\t ]+)(?P<optional_port>(?:[:](?P<port>\d+))?)(?P<path>/[^\r\n\t ]*)?)

用手寫(xiě)直接寫(xiě)是很難寫(xiě)出這么復(fù)雜的正則的,寫(xiě)出來(lái)也很難調(diào)試,而組合方式構(gòu)建正則的話,可以將小的簡(jiǎn)單正則提前測(cè)試好,要用的時(shí)候再組裝起來(lái),就不容易出錯(cuò),上面就是組裝替換后的結(jié)果。

下面用里面的 url 這個(gè)規(guī)則來(lái)匹配一下:

# 使用規(guī)則 "url" 進(jìn)行匹配
pattern = m['url']
s = re.match(pattern, 'https://name:pass@www.baidu.com:8080/haha')

# 打印完整匹配結(jié)果
print('matched: "%s"'%s.group(0))
print()

# 打印分組匹配結(jié)果
for name in ('url', 'login_name', 'login_pass', 'host', 'port', 'path'):
    print('subgroup:', name, '=', s.group(name))

輸出:

match text with pattern "url"
matched: "https://name:pass@www.baidu.com:8080/haha"

subgroup: url = https://name:pass@www.baidu.com:8080/haha
subgroup: login_name = name
subgroup: login_pass = pass
subgroup: host = www.baidu.com
subgroup: port = 8080
subgroup: path = /haha

可以取完整結(jié)果,也可以按照規(guī)則名字,取得里面具體某個(gè)部件得匹配結(jié)果。

這下可以方便的寫(xiě)復(fù)雜正則表達(dá)式了。

再 Python 的正則表達(dá)式里 {xxx} 是用來(lái)表示長(zhǎng)度的,里面都是數(shù)字,如果里面是變量名的話不會(huì)和原有規(guī)則沖突,因此這個(gè)寫(xiě)法是安全的。

實(shí)現(xiàn)代碼:

import re

# 將 pattern 里形如 {name} 的文本,用 macros 里的預(yù)定義規(guī)則替換
def regex_expand(macros, pattern, guarded = True):
    output = []
    pos = 0
    size = len(pattern)
    while pos < size:
        ch = pattern[pos]
        if ch == '\\':
            output.append(pattern[pos:pos + 2])
            pos += 2
            continue
        elif ch != '{':
            output.append(ch)
            pos += 1
            continue
        p2 = pattern.find('}', pos)
        if p2 < 0:
            output.append(ch)
            pos += 1
            continue
        p3 = p2 + 1
        name = pattern[pos + 1:p2].strip('\r\n\t ')
        if name == '':
            output.append(pattern[pos:p3])
            pos = p3
            continue
        elif name[0].isdigit():
            output.append(pattern[pos:p3])
            pos = p3
            continue
        elif ('<' in name) or ('>' in name):
            raise ValueError('invalid pattern name "%s"'%name)
        if name not in macros:
            raise ValueError('{%s} is undefined'%name)
        if guarded:
            output.append('(?:' + macros[name] + ')')
        else:
            output.append(macros[name])
        pos = p3
    return ''.join(output)

# 給定規(guī)則文本,構(gòu)建規(guī)則字典
def regex_build(code, macros = None, capture = True):
    defined = {}
    if macros is not None:
        for k, v in macros.items():
            defined[k] = v
    line_num = 0
    for line in code.split('\n'):
        line_num += 1
        line = line.strip('\r\n\t ')
        if (not line) or line.startswith('#'):
            continue
        pos = line.find('=')
        if pos < 0:
            raise ValueError('%d: not a valid rule'%line_num)
        head = line[:pos].strip('\r\n\t ')
        body = line[pos + 1:].strip('\r\n\t ')
        if (not head):
            raise ValueError('%d: empty rule name'%line_num)
        elif head[0].isdigit():
            raise ValueError('%d: invalid rule name "%s"'%(line_num, head))
        elif ('<' in head) or ('>' in head):
            raise ValueError('%d: invalid rule name "%s"'%(line_num, head))
        try:
            pattern = regex_expand(defined, body, guarded = not capture)
        except ValueError as e:
            raise ValueError('%d: %s'%(line_num, str(e)))
        try:
            re.compile(pattern)
        except re.error:
            raise ValueError('%d: invalid pattern "%s"'%(line_num, pattern))
        if not capture:
            defined[head] = pattern
        else:
            defined[head] = '(?P<%s>%s)'%(head, pattern)
    return defined

# 定義一套組合規(guī)則
rules = r'''
    protocol = http|https
    login_name = [^:@\r\n\t ]+
    login_pass = [^@\r\n\t ]+
    login = {login_name}(:{login_pass})?
    host = [^:/@\r\n\t ]+
    port = \d+
    optional_port = (?:[:]{port})?
    path = /[^\r\n\t ]*
    url = {protocol}://({login}[@])?{host}{optional_port}{path}?
'''

# 將上面的規(guī)則展開(kāi)成字典
m = regex_build(rules, capture = True)

# 輸出字典內(nèi)容
for k, v in m.items(): 
    print(k, '=', v)

print()

# 用最終規(guī)則 "url" 匹配文本
pattern = m['url']
s = re.match(pattern, 'https://name:pass@www.baidu.com:8080/haha')

# 打印完整匹配
print('matched: "%s"'%s.group(0))
print()

# 按名字打印分組匹配
for name in ('url', 'login_name', 'login_pass', 'host', 'port', 'path'):
    print('subgroup:', name, '=', s.group(name))

完事,主要邏輯 84 行代碼。

到此這篇關(guān)于Python如何使用組合方式構(gòu)建復(fù)雜正則的文章就介紹到這了,更多相關(guān)Python構(gòu)建復(fù)雜正則內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 簡(jiǎn)單了解python 郵件模塊的使用方法

    簡(jiǎn)單了解python 郵件模塊的使用方法

    這篇文章主要介紹了簡(jiǎn)單了解python 郵件模塊的使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-07-07
  • python爬取2021貓眼票房字體加密實(shí)例

    python爬取2021貓眼票房字體加密實(shí)例

    在本篇文章里小編給大家整理的是一篇關(guān)于python爬取2021貓眼票房字體加密實(shí)例內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。
    2021-02-02
  • OPENCV去除小連通區(qū)域,去除孔洞的實(shí)例講解

    OPENCV去除小連通區(qū)域,去除孔洞的實(shí)例講解

    今天小編就為大家分享一篇OPENCV去除小連通區(qū)域,去除孔洞的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06
  • pandas中Series和DataFrame的rank方法解析

    pandas中Series和DataFrame的rank方法解析

    pandas中的rank方法是用于數(shù)據(jù)排名的重要工具,它不返回排序后的數(shù)據(jù),而是數(shù)據(jù)的排名。rank方法可以處理相同數(shù)據(jù)的排名,通過(guò)平均排名方式解決排名沖突,并支持自定義排序規(guī)則及逆序排名。此外,DataFrame的rank方法允許在行或列上計(jì)算排名
    2024-09-09
  • python實(shí)現(xiàn)隨機(jī)調(diào)用一個(gè)瀏覽器打開(kāi)網(wǎng)頁(yè)

    python實(shí)現(xiàn)隨機(jī)調(diào)用一個(gè)瀏覽器打開(kāi)網(wǎng)頁(yè)

    下面小編就為大家分享一篇python實(shí)現(xiàn)隨機(jī)調(diào)用一個(gè)瀏覽器打開(kāi)網(wǎng)頁(yè),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-04-04
  • 最新python 字符串?dāng)?shù)組互轉(zhuǎn)問(wèn)題

    最新python 字符串?dāng)?shù)組互轉(zhuǎn)問(wèn)題

    這篇文章主要介紹了最新python 字符串?dāng)?shù)組互轉(zhuǎn)問(wèn)題,主要介紹了字符串轉(zhuǎn)list數(shù)組問(wèn)題和list數(shù)組轉(zhuǎn)字符串問(wèn)題,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • pip指定python位置安裝軟件包的方法

    pip指定python位置安裝軟件包的方法

    今天小編就為大家分享一篇pip指定python位置安裝軟件包的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-07-07
  • 刪除目錄下相同文件的python代碼(逐級(jí)優(yōu)化)

    刪除目錄下相同文件的python代碼(逐級(jí)優(yōu)化)

    讓我們來(lái)分析一下這個(gè)問(wèn)題:首先,文件個(gè)數(shù)非常多,手工查找是不現(xiàn)實(shí)的,再說(shuō),單憑我們?nèi)庋?,在幾千張圖片里面找到完全相同的難度也是很大的
    2012-05-05
  • Django的HttpRequest和HttpResponse對(duì)象詳解

    Django的HttpRequest和HttpResponse對(duì)象詳解

    這篇文章主要介紹了Django的HttpRequest和HttpResponse對(duì)象,分享了相關(guān)代碼示例,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-01-01
  • 手把手帶你用python爬取小姐姐私房照

    手把手帶你用python爬取小姐姐私房照

    這篇文章主要介紹了用python如何爬取小姐姐私房照,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08

最新評(píng)論

怀化市| 康定县| 温州市| 麻江县| 瓮安县| 山阴县| 日土县| 武城县| 辽宁省| 石家庄市| 剑川县| 齐河县| 湾仔区| 威海市| 甘孜| 宜阳县| 鄂温| 宁远县| 耿马| 含山县| 榆林市| 海城市| 广东省| 黄平县| 漾濞| 天津市| 滁州市| 石首市| 桂阳县| 合江县| 威远县| 巴塘县| 织金县| 仪陇县| 宾川县| 贺州市| 湘潭市| 南平市| 邹城市| 井研县| 奉化市|