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

歡迎訪問 生活随笔!

生活随笔

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

python

python 正则表达式 断言 不定长表达式_MyEssay 之 Python正则表达式 —— 四种断言扩展的理解...

發布時間:2023/12/10 python 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python 正则表达式 断言 不定长表达式_MyEssay 之 Python正则表达式 —— 四种断言扩展的理解... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我們經常用正則表達式來檢測一個字符串中包含某個子串,要表示一個字符串中不包含單個的某字符或某些字符也很容易,用[^...]形式就可以了。但是要表示一個字符串中不包含某個子串(由字符序列構成)的時候,用[^...]這種形式就不行了,此時就需要使用到四種正則表達式的擴展匹配了,即所謂的“正向前行匹配” ?(?=...)、“負向前行匹配” (?!...)、"正向后行匹配" (?<=...) ?、“負向后行匹配”(?文中的描述,從兩個方面入手:

所謂的前行(lookahead)和后行(lookbehind),其實就是向前看和向后看的意思。正則表達式引擎在執行字符串和表達式匹配時,會從頭到尾(從前到后)連續掃描字符串中的字符,設想有一個掃描指針指向字符邊界處并隨匹配過程移動。前行斷言,是當掃描指針位于某個位置時,引擎會嘗試匹配指針還未掃過的字符,先于指針到達該字符,故稱為前行。后行斷言,引擎會嘗試匹配指針已掃過的字符,后于指針到達該字符,故稱為后行。

記憶方式:后行斷言(?<=pattern)、(?

所謂的正向(positive)和負向(negative):正向就表示匹配括號中的表達式,負向表示不匹配。

記憶方式:不等于(!=)、邏輯非(!)都是用!號來表示,所以有!號的形式表示不匹配、負向;將!號換成=號,就表示匹配、正向。

我們特別需要注意的一點是,對于后行方式的兩種斷言(?<=...)和(?

line0 = ‘?#?def???func(funcName, funcParam, funcTime=360) ‘

line1 =?‘?def???func(funcName, funcParam, funcTime=360) ‘

line2 =?"????obj1(param).func(‘func1‘, ‘param1‘, funcTime=150) # test"

line3 =?"??obj2().funcTest(1) ?# obj1(param).func(‘func1‘, ‘param1‘)"

我們希望字符串中包含對函數 func()的調用,即在被測試line中出現 "func("字符串,但是在被測line中卻又不包含針對函數func的定義,即不能出現 “def func(” 字符串,并且def 和 func 之間可能包含多個空格。按照最直接的思路,為要匹配 "func("?字符串,并且是在 "func("?前面不出現 “def\s+”模式的字符串,所以首先考慮使用向后看的方法,即負向后行匹配方式來應用于line1,即 re.findall(r"(?

>>> re.findall(r"(?

[‘???func(‘]

"func"前為三個空格;這是為什么呢?原因是re引擎會去嘗試找到一個 "\s*func\(" 模式的字符串,并且在這個字符串前面不會出現 "def?"?字符串(def后有一個空格),包含三個前置空格的 "???func("?正好就能滿足條件,首先它能夠匹配 "\s*func\(" 的模式,并且這個字符串前面的是不含空格的 "def" 字符串,而不是在負向后行匹配斷言(?

那么嘗試將負向后行匹配斷言中def后面的空格去掉,即修改為?re.findall("(?

>>> re.findall(r"(?

[‘??func(‘]

"func"前為兩個空格——仔細分析會發現這是因為原因是re引擎會去嘗試找到一個“\s*func\(”模式的字符串,并且在這個字符串前面不會出現“def”字符串(def后沒有空格),包含2個前置空格的 "??func(" 就正好滿足條件,因為包含2個空格的 "??func("?字符串能夠匹配 "\s*func\(" 的模式,并且這個字符串前面的是后接了一個空格的 "def?"?字符串,而不是在負向后行匹配斷言pattern "(?

再嘗試在負向后行匹配斷言中在def后面使用\s+,即修改為??re.findall("(?

——所以,對于在 def 和 func之間包含了三個空格的line1,要想用負向后行斷言來實現匹配,必須使用def后包含三個空格而func前無空格的?re.findall("(?

于是我們只能考慮采取負向前行斷言來實現精確匹配,即 re.findall("^(?!.*def\s+func\().*func\(", line1),執行得到的結果為空列表[],同時我們使用正向前行斷言來驗證我們的匹配字符串使用正確,即執行?re.findall("^(?=.*def\s+func\().*func\(", line1),得到的結果為?[‘def ? func(‘]

>>> re.findall("^(?!.*def\s+func\().*func\(", line1)

[]

>>> re.findall("^(?=.*def\s+func\().*func\(", line1)

[‘?def???func(‘]

—— 這說明我們的負向前行斷言正好精確匹配到了 def 和 func 之間存在不定長度空格數的情況。

此處再來解析一下這里的負向前行斷言的含義:"^(?!.*def\s+func\().*func\(" ?表示從line的起始位置開始向后搜索,不允許出現 ".*def\s+func\(" 這種模式的字符串,但又嘗試在此前提下尋找能夠匹配 ?".*func\(" 模式的字符串,這也就正是我們所希望的過濾條件。此處的?(?!.*def\s+func\()?是不消耗任何字符串長度的

這里需要特別注意的是另外兩種與 re.findall("^(?!.*def\s+func\().*func\(", line1) 很接近的匹配模式:

1、如果使用的是??re.findall("^(?!def\s+func\().*func\(", line1),執行的結果將不會是預期的空列表,而是?[‘ def???func(‘],這是因為這種寫法,RE引擎將會嘗試搜索是否存在起始位置開始不是 "def\s+func\(" 而是 ".*func\(" 的字符串,但是line1中的"def"前面正好有一個空格,所以RE引擎發現從開始位置處搜索到的是帶一個前置空格的 "?def\s+func\(" 模式的字符串,而不是負向前表達式中沒有空格的 "def\s+func\(" 模式字符串,所以會匹配成功。

2、如果使用的是 re.findall("(?!.*def\s+func\().*func\(", line1),執行的結果也不會是預期的空列表,而是 [ ‘ef???func(‘ ],這是因為如果pattern中沒有了^字符,就不是要求line1從開始就必須滿足匹配條件,而是line1中任意位置能夠滿足匹配條件都可以,所以line1中的 "ef???func(" 這個字符串就能滿足匹配條件

——?綜上所述,建議嘗試正則匹配“在xxx之前不出現yyy,且 xxx 和 yyy 之間可能存在其他不定長字符串”的場景時,優先考慮使用負向前行斷言; 對于能夠確定xxx和yyy之間是定長的情況下,可以使用負向后行斷言

再例如考慮在line3中匹配 "func(" 字符串的時候,要求在 "func(" 前不能出現#符號,即要求func函數的調用語句沒有被注釋掉,因為 # 和 func( 之間的字符長度完全是隨機未知的,故應該使用負向想前行斷言方式的 re.findall("^(?!.*#.*func\().*func\(", line3),而不是 re.findall("(?

原文:http://www.cnblogs.com/xaviercd/p/5818731.html

總結

以上是生活随笔為你收集整理的python 正则表达式 断言 不定长表达式_MyEssay 之 Python正则表达式 —— 四种断言扩展的理解...的全部內容,希望文章能夠幫你解決所遇到的問題。

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