目前在使用Python分析邏輯運算跟一些函式的組合
用正規表示式抓函式時碰到一個問題
我使用re去找比對符合的函式
但是函式中如果還有左右括號的話要如何寫正規表示式呢?
如:(C("STA and Ppe (SP)") or (A("abc def g") and A(hij) and (B(klm-n0) or A-B(op qr st(oqs))))) and A(Curaçao)
我的正規表示式:[A-Z-]+([\w" -]+)
就會選取到
A("abc def g")
A(hij)
B(klm-n0)
A(Curaçao)
但
C("STA and Ppe (SP)")跟A-B(op qr st(oqs))就沒辦法選取到
可是如果在正規表示式加了左右括號:[A-Z-]+([\w" -()]+)
就會將整個字串視為C(......)
請問應該如何修正我的正規表示式呢?謝謝
你的 RE 中的小括號沒有加 \ 跳脫,結果應該是錯的吧?用
[A-Z-]+\([\w" \(-]+\)?"?\)
試試看:
grep -Po '[A-Z-]+\([\w" \(-]+\)?"?\)' <<<'(C("STA and Ppe (SP)") or (A("abc def g") and A(hij) and (B(klm-n0) or A-B(op qr st(oqs))))) and A(Curacao)'
C("STA and Ppe (SP)")
A("abc def g")
A(hij)
B(klm-n0)
A-B(op qr st(oqs))
A(Curacao)
不好意思,因為編輯時沒注意到用程式碼的格式顯示,所以貼上的斜線消失了。原來是有加的。
感謝你的解答。
如果函式裡的括弧並不是在句尾,或是函式裡的括弧不只一個的話,似乎就不適用這個寫法。這邊再加碼詢問一下,如果是這種情形,例如裡面其中一個函式是:G(dd rr h(drh) sss oo k (sok) gg),也就是無法預測函式中括弧的數量及位置,這樣有辦法用正規表示式來處理嗎?
(?P<foo>[A-G])\((?P<bar>.+)\)
這樣?
當然沒問題
[A-Z-]+\([\w" -]*(\([\w" -]*\)[\w" -]*)*\)
感謝!!太厲害了!!
原來可以用group的方法來拆。
所以也可以改寫成這樣嗎?
[A-Z-]+\(([\w" -]*\([\w" -]*\))*[\w" -]*\)
不知道我這樣理解對不對?
結果我在
https://regex101.com/
這個網站檢查是沒有問題的
但是實際用python去跑
[A-Z-]+\([\w" -]*\)
可以篩出函式的參數內沒有左右括號的函式
但加上左右括弧的群組功能就全部篩不出來
[A-Z-]+\([\w" -]*(\([\w" -]*\)[\w" -]*)*\)
理論上左右括弧的群組後面加米字
就算括弧中的表示式寫錯
也應該可以篩出函式的參數內沒有左右括號的函式
可是什麼都篩不出來
是不是有其他的問題?
那最有可能的是這個 RE 在 python 的字串中並不是我們想的那樣。
你可以貼出 python 程式碼會比較好找問題。
我發現問題跟解法了
我原來是用re.findall
我的程式是這樣寫的
import re
pattern = r'[A-Z-]+\([\w" -]*(\([\w" -]*\)[\w" -]*)*\)'
temp_text= '(C("STA and Ppe (SP)") or (A("abc def g") and A(hij) and (B(klm-n0) or A-B(op qr st(oqs))))) and A(Curaçao)'
function_list = re.findall(pattern,temp_text)
print(function_list)
那麼結果就是
['(SP)"', '', '', '', '(oqs)', '']
程式只跑出正規表示式中group內的內容,而不是整個函式。
後來改成用re.finditer
import re
pattern = r'[A-Z-]+\([\w" -]*(\([\w" -]*\)[\w" -]*)*\)'
temp_text= '(C("STA and Ppe (SP)") or (A("abc def g") and A(hij) and (B(klm-n0) or A-B(op qr st(oqs))))) and A(Curaçao)'
function_list = re.finditer(pattern,temp_text, re.I)
for i in function_list:
print(i.group())
執行結果是
C("STA and Ppe (SP)")
A("abc def g")
A(hij)
B(klm-n0)
A-B(op qr st(oqs))
A(Curaçao)
這樣程式可以跑出整個函式。
但不知道有沒有用findall可以抓到整個函式的辦法啊?
你誤會了 findall 返回陣列的意義了。它返回的是括號內的內容,也就是有括號才有返回值。
意思就是如果你要它返回整個符合字串,那就是把整個 re 用 () 括起來。
pattern = r'([A-Z-]+\([\w" -]*(\([\w" -]*\)[\w" -]*)*\))'
原來是這樣。網路上的範例很少在正規表示式中使用群組,也沒有特別加括弧使用,所以都省略掉了。感謝!!