日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python正则表达式之扩展语法(5)

發布時間:2025/3/21 python 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python正则表达式之扩展语法(5) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

非捕獲組和命名組

精心設計的正則表達式可能會劃分很多組,這些組不僅可以匹配相關的子串,還能夠對正則表達式本身進行分組和結構化。在復雜的正則表達式中,由于有太多的組,因此通過組的序號來跟蹤和使用會變得困難。有兩個新的功能可以幫你解決這個問題——非捕獲組和命名組——它們都使用了一個公共的正則表達式擴展語法。我們先來看看這個表達式擴展語法是什么。

正則表達式的擴展語法:

眾所周知,Perl 5 為標準的正則表達式增加了許多強大的功能。Perl 的開發者們并不能選擇一個新的元字符或者通過反斜杠構造一個新的特殊序列來實現擴展的功能。因為這樣會和標準的正則表達式發生沖突。比如你想選擇 & 作為擴展功能的元字符(在標準正則表達式中,& 沒有特殊意義),但這樣的話,已經按照標準語法寫出來的正則表達式就不得不修改,因為它們中包含的 '&' 意愿上只是把它當做普通字符來匹配而已。

最終,Perl 的開發者們決定使用 (?...) 作為擴展語法。問號 ? 緊跟在左小括號 ( 后邊,本身是一個語法錯誤的寫法,因為 ? 前邊沒有東西可以重復,所以這樣就解決了兼容性的問題(理由是語法正確的正則表達式肯定不會這么寫)。然后,緊跟在 ? 后邊的字符則表示哪些擴展語法會被使用。例如 (?=foo) 表示一種新的擴展功能前向斷言),(?:foo) 則表示另一種擴展功能(一個包含子串 foo 的非捕獲組)。

Python 支持 Perl 的一些擴展語法,并且在此基礎上還增加了一個擴展語法。如果緊跟在問號 ? 后邊的是 P,那么可以肯定這是一個 Python 的擴展語法。

非捕獲組

第一個我們要講的是非捕獲組。有時候你知識需要用一個組來表示部分正則表達式,你并不需要這個組去匹配任何東西,這時你可以通過非捕獲組來明確表示你的意圖。非捕獲組的語法是 (?:...),這個 … 你可以替換為任何正則表達式。

>>> m = re.match("([abc])+", "abc") >>> m.groups() ('c',) >>> m = re.match("(?:[abc])+", "abc") >>> m.groups() ()

“捕獲”就是匹配的意思啦,普通的子組都是捕獲組,因為它們能從字符串中匹配到數據

除了你不能從非捕獲組獲得匹配的內容之外,其他的非捕獲組跟普通子組沒有什么區別了。你可以在里邊放任何東西使用重復功能的元字符或者跟其他子組進行嵌套捕獲的或者非捕獲的子組都可以)。

當你需要修改一個現有的模式的時候,(?:...) 是非常有用的。原始是添加一個非捕獲組并不會影響到其他(捕獲)組的序號。值得一提的是,在搜索的速度上,捕獲組和非捕獲組的速度是沒有任何區別的。

命名組

我們再來看另外一個重要功能:命名組。普通子組我們使用序列來訪問它們命名組則可以使用一個有意義的名字來進行訪問

命名組的語法是 Python 特有的擴展語法:(?P<name>)。很明顯,< > 里邊的 name 就是命名組的名字啦。命名組除了有一個名字標識之外,跟其他捕獲組是一樣的。

匹配對象的所有方法不僅可以處理那些由數字引用的捕獲組,還可以處理通過字符串引用的命名組。除了使用名字訪問**,命名組仍然可以使用數字序號進行訪問**:

>>> p = re.compile(r'(?P<word>\b\w+\b)') >>> m = p.search( '(((( Lots of punctuation )))' ) >>> m.group('word') 'Lots' >>> m.group(1) 'Lots'

命名組非常好用,因為它讓你可以使用一個好記的名字代替一些毫無意義的數字。下邊是來自 imaplib 模塊的例子:

InternalDate = re.compile(r'INTERNALDATE "'r'(?P<day>[ 123][0-9])-(?P<mon>[A-Z][a-z][a-z])-'r'(?P<year>[0-9][0-9][0-9][0-9])'r' (?P<hour>[0-9][0-9]):(?P<min>[0-9][0-9]):(?P<sec>[0-9][0-9])'r' (?P<zonen>[-+])(?P<zoneh>[0-9][0-9])(?P<zonem>[0-9][0-9])'r'"')

很明顯,使用 m.group('zonem') 訪問匹配內容要比使用數字 9 更簡單明了。

正則表達式中,反向引用的語法像 (...)\1 是使用序號的方式來訪問子組;在命名組里,顯然也是有對應的變體使用名字來代替序號。其擴展語法是 (?P=name),含義是該 name 指向的組需要在當前位置再次引用。那么搜索兩個單詞的正則表達式可以寫成 (\b\w+)\s+\1,也可以寫成 (?P<word>\b\w+)\s+(?P=word):

>>> p = re.compile(r'(?P<word>\b\w+)\s+(?P=word)') >>> p.search('Paris in the the spring').group() 'the the'

前向斷言

我們要講解的另一個零寬斷言是前向斷言,前向斷言可以分為前向肯定斷言和前向否定斷言兩種形式。

(?=...)

前向肯定斷言。如果當前包含的正則表達式(這里以 … 表示)在當前位置成功匹配,則代表成功,否則失敗。一旦該部分正則表達式被匹配引擎嘗試過,就不會繼續進行匹配了;剩下的模式在此斷言開始的地方繼續嘗試。

(?!...)

前向否定斷言。這跟前向肯定斷言相反(不匹配則表示成功,匹配表示失敗)。

為了使大家更易懂,我們舉個例子來證明這玩意是真的很有用。大家考慮一個簡單的正則表達式模式,這個模式的作用是匹配一個文件名。我們都知道,文件名是用 . 將名字和擴展名分隔開的。例如在 fishc.txt 中,fish 是文件的名字,.txt 是擴展名。

這個正則表達式其實挺簡單的:.*[.].*$

注意,這里用于分隔的 . 是一個元字符,所以我們使用 [.] 剝奪了它的特殊功能。還有 $,我們使用 $ 確保字符串剩余的部分都包含在擴展名中。所以這個正則表達式可以匹配 fishc.txt,foo.bar,autoexec.bat,sendmail.cf,printers.conf 等。

現在我們來考慮一種復雜一點的情況,如果你想匹配擴展名不是 bat 的文件,你的正則表達式應該怎么寫呢?
我們先來看下你有可能寫錯的嘗試:

.*[.][^b].*$

這里為了排除 bat,我們先嘗試排除擴展名的第一個字符為非 b。但這是錯誤的開始,因為 foo.bar 后綴名的第一個字符也是 b。

為了彌補剛剛的錯誤,我們試了這一招:

.*[.]([^b]..|.[^a].|..[^t])$

我們不得不承認,這個正則表達式變得很難看…但這樣第一個字符不是 b,第二個字符不是 a,第三個字符不是 t…這樣正好可以接受 foo.bar,排除 autoexec.bat。但問題又來了,這樣的正則表達式要求擴展名必須是三個字符,比如 sendmail.cf 就會被排除掉。

好吧,我們接著修復問題:

.*[.]([^b].?.?|.[^a]?.?|..?[^t]?)$

在第三次嘗試中,我們讓第二個和第三個字符變成可選的。這樣就可以匹配稍短的擴展名,比如 sendmail.cf。

不得不承認,我們把事情搞砸了,現在的正則表達式變得艱澀難懂外加奇丑無比!!

更慘的是如果需求改變了,例如你想同時排除 bat 和 exe 擴展名,這個正則表達式模式就變得更加復雜了…

當當當當!主角登場,其實,一個前向否定斷言就可以解決你的難題:

.*[.](?!bat$).*$

我們來解釋一下這個前向否定斷言的含義:如果正則表達式 bat 在當前位置不匹配,嘗試剩下的部分正則表達式;如果 bat 匹配成功,整個正則表達式將會失敗(因為是前向否定斷言嘛_)。(?!bat$) 末尾的 $ 是為了確保可以正常匹配像 sample.batch 這種以 bat 開始的擴展名

同樣,有了前向否定斷言,要同時排除 bat 和 exe 擴展名,也變得相當容易:

.*[.](?!bat$|exe$).*$

總結

以上是生活随笔為你收集整理的Python正则表达式之扩展语法(5)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 91精选视频 | 欧美日韩激情一区二区 | 欧美性受xxxxx | 午夜青青草 | 欧美日韩国产一区二区 | 人人综合 | 尤物视频在线 | 中文字幕一区二区人妻视频 | 91草草草 | 台湾swag在线播放 | 成人黄色免费视频 | 好吊妞无缓冲视频观看 | 久久久久麻豆v国产精华液好用吗 | 亚欧综合在线 | 夜晚福利视频 | 国产精品久久久久久精 | 久久久久成人精品无码中文字幕 | 麻豆91精品91久久久 | 人妻精品一区一区三区蜜桃91 | 一区二区免费播放 | 国产精品久久久久不卡 | 国产97色在线 | 国产 | www视频在线| 亚洲在线播放 | 日本中文字幕网站 | 欧美精品手机在线 | 99视频免费 | 日韩av一| 亚洲在线资源 | 日韩欧洲亚洲AV无码精品 | 女王脚交玉足榨精调教 | 波多野结衣在线观看视频 | 欧美一区二区 | 久久综合久久久久 | 国产伊人久久 | 亚洲av乱码久久精品蜜桃 | 青青青在线视频免费观看 | www九九九| 99精品福利视频 | 欧美日韩一区二区在线 | 特一级黄色片 | 国产一区二区三区麻豆 | www.色综合.com| 亚洲69| 国产精品呻吟 | 澳门黄色一级片 | 999久久精品 | 久久免费视频精品 | 久久性生活 | 美女一级| 丰满人妻中伦妇伦精品app | 日本精品一区二区 | 玖玖精品国产 | 国产片天天弄 | 日韩精品一区在线播放 | 年代下乡啪啪h文 | 樱花草av| 91免费网站视频 | 亚洲熟女少妇一区二区 | 黄色永久网站 | 强行挺进皇后紧窄湿润小说 | 欧美成人三级伦在线观看 | 午夜宅男影院 | 精品视频在线观看免费 | 国产伦精品一区二区三区四区免费 | 91精品区 | 久久精品视频偷拍 | 欧美xxx在线观看 | jizz国产在线观看 | 男人的天堂免费视频 | 中文字幕av在线免费观看 | 欧美激情18 | 欧美成人精品一区二区男人小说 | 粉色视频免费观看 | 337p日本欧洲亚洲鲁鲁 | 人妻换人妻a片爽麻豆 | 日韩福利视频一区 | 国产高清成人久久 | 在线视频中文 | 成人资源站 | 欧美精品乱码久久久久久 | 91精品国自产在线偷拍蜜桃 | 成人做爰视频www | 农村老女人av | 青青青手机视频 | 美女扒开腿让男人捅 | 成人黄色片在线观看 | 九九在线免费视频 | 亚洲av日韩av不卡在线观看 | 看黄免费网站 | 欧美黄色一区二区三区 | 亚洲成熟少妇 | 香蕉色网 | 亚洲天堂首页 | 久久精品三级视频 | 欧美麻豆视频 | 中文字幕乱码在线人视频 | 四虎成人精品永久免费av | 91九色在线播放 |