python正则匹配括号以及内容_【Python】正则表达式匹配最里层括号的内容
現在有一個字符串:
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)")))))'
我需要通過正則,匹配字符串中最里層的括號及其中的內容(不匹配引號內的括號),即:
str1 => (status_id = "C" OR level_id = "D")
str2 => (level_id = "D" AND subject_id = "(Cat)")
那么,這種超復雜的正則應該怎么寫?
如果正則實現不了,那么JS怎么來實現?
補充,對于 str1,我找到了這樣的正則可以滿足匹配:
\([^()]+\)
但是對于str2, 依然沒有辦法,期待大家解答!
回答
對于str2,我找到了這樣的
\([^()]*\"[^"]*\"[^()]*\)
看了一下需求我根本沒考慮用正則,好像太復雜了…直接上傳統方法吧;
可以使用運算優先級的思想,即用棧的數據結構來取得內部括號的內容;
技術要點:
匹配最內層的括號
引號內的內容不作為匹配標準
照著這個思路開始設計算法:
該算法是計算出要匹配的子字符串的 startIndex 和 endIndex 然后用 substring() 方法獲得子字符串;
當匹配到一個 "(" 字符的時,入棧,當我們匹配到第一個 ")" 時,出棧,即兩個索引之間的子字符串為目標字符串;
匹配到一個 "\"" 時,則停止匹配 "(" ,直到搜索到下一個 "\"" 時,才繼續開始搜索 "(" 。
拍腦袋想出來的算法,有不足之處歡迎補充。
//這樣,試試
/\(([^\(\)]*?”[^\”\(\)]*([^\”\(\)]+\)[^\(\)]*?\”[^\(\)]*)+)|([^\(\)]+\)/
補充:
分析需求 > 找到每個需求點的解決方案 > 整合解決方案 = 解決問題
分析需求:
需要匹配 ( a ) 的形式
其中 a 包含的字符有兩種可能,用a1和a2表示
a1含有一個或多個 b " c " b 形式的字符串,
其中 b 是一段不包括 ", ( 或 ) 的字符串
其中 c 是一段不包括 " 的字符串
a2中不含有 ( 或 )
逆向推導:
2.2 => a2 = [^\(\)]*
2.1.1 => b = [^\(\)\"]*
2.1.2 => c = [^\"]*
2.1 => a1= (b\"c\"b)+ = (b\"c\")+b =([^\(\)\"]*\"[^\"]*\")+[^\(\)\"]*
1 => \(a\) = \(a1\)|\(a2\) = \(([^\(\)\"]*\"[^\"]*\")+[^\(\)\"]*\)|\([^\(\)]*\)
正則表達式:
/\(([^\(\)\"]*\"[^\"]*\")+[^\(\)\"]*\)|\([^\(\)]*\)/
驗證:
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)
本題難點在需要對””進行遞歸統計,例如
(level_id = "D AND subject_id = "(Cat)"")
(cat)是符合要求的.
\([^()]*?\"((?:[^\"\"]|\"(?1)\")*+)\"[^()]*?\)|\([^()]*?\)
真愛生命,遠離正則,該正則可以滿足你的要求,php能用(php支持遞歸)java及Python無法使用.
推薦一個思路,找到(的index,切字符串處理
手機發不出正則 黑線
樓主的【^()】里如果不匹配()則繼續
把不匹配(的條件去掉,把貪婪的+改成*?即可
console.log(‘(subject_id = “A” OR (status_id = “Open” AND (status_id = “C” OR level_id = “D”)))’.match(/(
() ?
用正則匹配會比較復雜,建議 把干擾串 “( 和 )” 替換掉,比如 “[, ]”,再用簡單的正則替換,之后再換回來。
正則用 Python 實現如下:
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)")
總結
以上是生活随笔為你收集整理的python正则匹配括号以及内容_【Python】正则表达式匹配最里层括号的内容的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: InDesign 教程:如何更改内容颜色
- 下一篇: 联想服务器usb虚拟引入,联想Think