iT邦幫忙

0

請問正規表示式的問題

  • 分享至 

  • xImage

目前在使用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(......)

請問應該如何修正我的正規表示式呢?謝謝

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

0
wiseguy
iT邦超人 1 級 ‧ 2022-11-24 00:15:13
最佳解答

你的 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)

看更多先前的回應...收起先前的回應...
lsesroom iT邦新手 3 級 ‧ 2022-11-24 09:26:47 檢舉

不好意思,因為編輯時沒注意到用程式碼的格式顯示,所以貼上的斜線消失了。原來是有加的。

感謝你的解答。

如果函式裡的括弧並不是在句尾,或是函式裡的括弧不只一個的話,似乎就不適用這個寫法。這邊再加碼詢問一下,如果是這種情形,例如裡面其中一個函式是:G(dd rr h(drh) sss oo k (sok) gg),也就是無法預測函式中括弧的數量及位置,這樣有辦法用正規表示式來處理嗎?

froce iT邦大師 1 級 ‧ 2022-11-24 16:32:19 檢舉
(?P<foo>[A-G])\((?P<bar>.+)\)

這樣?

wiseguy iT邦超人 1 級 ‧ 2022-11-24 22:55:51 檢舉

當然沒問題

[A-Z-]+\([\w" -]*(\([\w" -]*\)[\w" -]*)*\)
lsesroom iT邦新手 3 級 ‧ 2022-11-25 10:20:02 檢舉

感謝!!太厲害了!!
原來可以用group的方法來拆。
所以也可以改寫成這樣嗎?

[A-Z-]+\(([\w" -]*\([\w" -]*\))*[\w" -]*\)

不知道我這樣理解對不對?

lsesroom iT邦新手 3 級 ‧ 2022-11-25 16:37:47 檢舉

結果我在
https://regex101.com/
這個網站檢查是沒有問題的

但是實際用python去跑

[A-Z-]+\([\w" -]*\)

可以篩出函式的參數內沒有左右括號的函式

但加上左右括弧的群組功能就全部篩不出來

[A-Z-]+\([\w" -]*(\([\w" -]*\)[\w" -]*)*\)

理論上左右括弧的群組後面加米字
就算括弧中的表示式寫錯
也應該可以篩出函式的參數內沒有左右括號的函式
可是什麼都篩不出來
是不是有其他的問題?

wiseguy iT邦超人 1 級 ‧ 2022-11-27 17:45:00 檢舉

那最有可能的是這個 RE 在 python 的字串中並不是我們想的那樣。
你可以貼出 python 程式碼會比較好找問題。

lsesroom iT邦新手 3 級 ‧ 2022-11-28 10:22:46 檢舉

我發現問題跟解法了
我原來是用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可以抓到整個函式的辦法啊?

wiseguy iT邦超人 1 級 ‧ 2022-11-28 20:08:09 檢舉

你誤會了 findall 返回陣列的意義了。它返回的是括號內的內容,也就是有括號才有返回值。
意思就是如果你要它返回整個符合字串,那就是把整個 re 用 () 括起來。

pattern = r'([A-Z-]+\([\w" -]*(\([\w" -]*\)[\w" -]*)*\))'
lsesroom iT邦新手 3 級 ‧ 2022-11-29 08:21:22 檢舉

原來是這樣。網路上的範例很少在正規表示式中使用群組,也沒有特別加括弧使用,所以都省略掉了。感謝!!

我要發表回答

立即登入回答