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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python正则匹配括号以及内容_【Python】正则表达式匹配最里层括号的内容

發(fā)布時間:2024/1/1 python 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python正则匹配括号以及内容_【Python】正则表达式匹配最里层括号的内容 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

現(xiàn)在有一個字符串:

str1 = '(subject_id = "A" OR (status_id = "Open" AND (status_id = "C" OR level_id = "D")))'

或者

str2 = '(subject_id = "A" OR subject_id = "Food" OR (subject_id = "C" OR (status_id = "Open" AND (status_id = "C" OR (level_id = "D" AND subject_id = "(Cat)")))))'

我需要通過正則,匹配字符串中最里層的括號及其中的內(nèi)容(不匹配引號內(nèi)的括號),即:

str1 => (status_id = "C" OR level_id = "D")

str2 => (level_id = "D" AND subject_id = "(Cat)")

那么,這種超復(fù)雜的正則應(yīng)該怎么寫?

如果正則實現(xiàn)不了,那么JS怎么來實現(xiàn)?

補充,對于 str1,我找到了這樣的正則可以滿足匹配:

\([^()]+\)

但是對于str2, 依然沒有辦法,期待大家解答!

回答

對于str2,我找到了這樣的

\([^()]*\"[^"]*\"[^()]*\)

看了一下需求我根本沒考慮用正則,好像太復(fù)雜了…直接上傳統(tǒng)方法吧;

可以使用運算優(yōu)先級的思想,即用棧的數(shù)據(jù)結(jié)構(gòu)來取得內(nèi)部括號的內(nèi)容;

技術(shù)要點:

匹配最內(nèi)層的括號

引號內(nèi)的內(nèi)容不作為匹配標(biāo)準(zhǔn)

照著這個思路開始設(shè)計算法:

該算法是計算出要匹配的子字符串的 startIndex 和 endIndex 然后用 substring() 方法獲得子字符串;

當(dāng)匹配到一個 "(" 字符的時,入棧,當(dāng)我們匹配到第一個 ")" 時,出棧,即兩個索引之間的子字符串為目標(biāo)字符串;

匹配到一個 "\"" 時,則停止匹配 "(" ,直到搜索到下一個 "\"" 時,才繼續(xù)開始搜索 "(" 。

拍腦袋想出來的算法,有不足之處歡迎補充。

//這樣,試試

/\(([^\(\)]*?”[^\”\(\)]*([^\”\(\)]+\)[^\(\)]*?\”[^\(\)]*)+)|([^\(\)]+\)/

補充:

分析需求 > 找到每個需求點的解決方案 > 整合解決方案 = 解決問題

分析需求:

需要匹配 ( a ) 的形式

其中 a 包含的字符有兩種可能,用a1和a2表示

a1含有一個或多個 b " c " b 形式的字符串,

其中 b 是一段不包括 ", ( 或 ) 的字符串

其中 c 是一段不包括 " 的字符串

a2中不含有 ( 或 )

逆向推導(dǎo):

2.2 => a2 = [^\(\)]*

2.1.1 => b = [^\(\)\"]*

2.1.2 => c = [^\"]*

2.1 => a1= (b\"c\"b)+ = (b\"c\")+b =([^\(\)\"]*\"[^\"]*\")+[^\(\)\"]*

1 => \(a\) = \(a1\)|\(a2\) = \(([^\(\)\"]*\"[^\"]*\")+[^\(\)\"]*\)|\([^\(\)]*\)

正則表達(dá)式:

/\(([^\(\)\"]*\"[^\"]*\")+[^\(\)\"]*\)|\([^\(\)]*\)/

驗證:

var reg = /\(([^\(\)\"]*\"[^\"]*\")+[^\(\)\"]*\)|\([^\(\)]*\)/;

'(the (quick "brown" fox "jumps over, (the) lazy" dog ))'

.match(reg)[0]

//"(quick "brown" fox "jumps over, (the) lazy" dog )"

'(the ("(quick)" brown fox "jumps (over, the)" lazy) dog )'

.match(reg)[0];

//"("(quick)" brown fox "jumps (over, the)" lazy)"

'(the (quick brown fox (jumps "over", ((the) "lazy"))) dog )'

.match(reg)[0];

//"(the)"

那就這么改:

substr=str.match(/\([^()]+\)/g)[0]

得到最里面括號及其中的值,后判斷該值前一位是否是 “,后一位是否是 ”:

index=str.indexOf(str.match(/\([^()]+\)/g)[0])

length=str.match(/\([^()]+\)/g)[0].length

str.substr(index+length,1)

str.substr(index-1,1)

如果不存在,則是需要的答案,如果存在,則先將str中substr替換掉,后在match一下,最后在替換回來:

str.replace(substr,"&&&")

str.replace(substr,"&&&").match(/\([^()]+\)/g)[0]

str.replace(substr,"&&&").match(/\([^()]+\)/g)[0].replace("&&&",substr)

本題難點在需要對””進行遞歸統(tǒng)計,例如

(level_id = "D AND subject_id = "(Cat)"")

(cat)是符合要求的.

\([^()]*?\"((?:[^\"\"]|\"(?1)\")*+)\"[^()]*?\)|\([^()]*?\)

真愛生命,遠(yuǎn)離正則,該正則可以滿足你的要求,php能用(php支持遞歸)java及Python無法使用.

推薦一個思路,找到(的index,切字符串處理

手機發(fā)不出正則 黑線

樓主的【^()】里如果不匹配()則繼續(xù)

把不匹配(的條件去掉,把貪婪的+改成*?即可

console.log(‘(subject_id = “A” OR (status_id = “Open” AND (status_id = “C” OR level_id = “D”)))’.match(/(

() ?

用正則匹配會比較復(fù)雜,建議 把干擾串 “( 和 )” 替換掉,比如 “[, ]”,再用簡單的正則替換,之后再換回來。

正則用 Python 實現(xiàn)如下:

import re

str1 = '(subject_id = "A" OR (status_id = "Open" AND (status_id = "C" OR level_id = "D")))'

str2 = '(subject_id = "A" OR subject_id = "Food" OR (subject_id = "C" OR (status_id = "Open" AND (status_id = "C" OR (level_id = "D" AND subject_id = "(Cat)")))))'

pat = re.compile(r"""(?<=[^"])

\([^()]+?

("\(.+?\)")*

\)

(?=[^"])

""", re.X)

print pat.search(str1).group(0)

print pat.search(str2).group(0)

輸出為:

(status_id = "C" OR level_id = "D")

(level_id = "D" AND subject_id = "(Cat)")

總結(jié)

以上是生活随笔為你收集整理的python正则匹配括号以及内容_【Python】正则表达式匹配最里层括号的内容的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。