我用Python嘗試判斷一個字串,假設字串為
query = "(test('abc') or tes('bcd') or te('cde')) and (test('efg') or tes('fgh') or te('ghi'))"
在字串中,我知道有test()、tes()、te()這些函式的存在,但不確定函式中的引數有哪些。
所以我想用for迴圈去跑這個字串,嘗試把字串結構化,可以用遞迴的方法處理它的樹狀結構。
for i in range(len(query)):
match(query[i]):
case('t'):
if(query.find('test(',i) == i):
#抓出函式中的引數進行處理
elif(query.find('tes(',i) == i):
#抓出函式中的引數進行處理
elif(query.find('te(',i) == i):
#抓出函式中的引數進行處理
case('o'):
if(query.find('or',i) == i):
#這邊有個OR
case('a'):
if(query.find('and',i) == i):
#這邊有個AND
我的問題是:假如程式在query[1]發現了"t",然後也用query.find('test(',1) == 1確認這個位置是test()函式,那我要如何在迴圈中跳過i=2~11的部分?
我試過在if的判斷式中加上函式的長度,例如:
for i in range(len(query)):
match(query[i]):
case('t'):
if(query.find('test(',i) == i):
i = i + 函式的長度
但迴圈還是會跑query[2]到query[11]的部分。
後來我在迴圈外加了一個skip的變數來決定continue的次數
skip = 0
for i in range(len(query)):
if(skip > 0):
skip = skip -1
continue
match(query[i]):
case('t'):
if(query.find('test(',i) == i):
skip = 計算出函式的長度
這個方法是有效的。
但我想問,還有沒有更聰明的寫法?
請各位提供我改進程式的意見,感謝
我知道Regular Expression,但我不太懂怎麼用Regular Expression寫?能否麻煩簡單的舉個例子,感謝。
我的想法是先解析query,再跑遞迴處理樹狀結構的問題。我PO的這一部分只有解析query的部分,解析的結果會寫進陣列,然後用另一段程式來跑遞迴。
能否麻煩簡單的舉個例子
我回答裡的超連結就有例子
我大概的想法是這樣:
可以用re把函式的位置跟引數的內容抓出來,
然後用迴圈判斷括號來處理樹狀的架構
是這樣嗎?
https://docs.python.org/zh-tw/3/howto/regex.html
tes?t?\((?P<params>[\w\'\"\, ]*)\)
直接給你正則表示法,自己去用 named group去把參數取出來再分割。
程式碼大概沒幾行就可以了。關鍵字和關鍵的表示法都給了,剩下你自己研究。
這種東西不用正則寫會搞死自己。
可能我問題沒有描述得很明確,因為在這個邏輯判斷的樹裡面還要做其他的處理,而我沒有把全部的程式內容都完整打出來。
上面網友的回覆也對我要處理的一些問題有所幫助,感謝
你給完整的,我們給的答案大概一樣也是正則表示法。
你這東西就是用正則做最快最簡單,加上python的正則有支援named group,你大可提取出你所需要的資訊,後面再去處理。
你給的東西,好像什麼程式考題喔。
老實說這東西用re模組真的比較方便啦,但如果你真的不想用的話為啥不嘗試用while+切片處理呢
i = 0
while i < (len(query)):
match(query[i]):
case('t'):
if(query.find('test(',i) == i):
#抓出函式中的引數進行處理
elif(query.find('tes(',i) == i):
#抓出函式中的引數進行處理
elif(query.find('te(',i) == i):
#抓出函式中的引數進行處理
query = query[i:]
i=-1
case('o'):
if(query.find('or',i) == i):
#這邊有個OR
query = query[i:]
i=-1
case('a'):
if(query.find('and',i) == i):
#這邊有個AND
query = query[i:]
i=-1
i+=1
但老實說,我不管怎麼想都覺得會出問題啦,建議別用,乖乖用re得永生
Python 有 label 可以應用.
https://peps.python.org/pep-3136/
libcst 可以試試看
https://libcst.readthedocs.io/en/latest/index.html
import libcst
q1 = "(test('abc') or tes('bcd') or te('cde')) and (test('efg') or tes('fgh') or te('ghi'))"
libcst.parse_expression(q1)
BooleanOperation(
left=BooleanOperation(
left=BooleanOperation(
left=Call(
func=Name(
value='test',
lpar=[],
rpar=[],
),
args=[
Arg(
value=SimpleString(
value="'abc'",
lpar=[],
rpar=[],
),
keyword=None,
equal=MaybeSentinel.DEFAULT,
comma=MaybeSentinel.DEFAULT,
star='',
whitespace_after_star=SimpleWhitespace(
value='',
),
whitespace_after_arg=SimpleWhitespace(
value='',
),
),
],
lpar=[],
rpar=[],
whitespace_after_func=SimpleWhitespace(
value='',
),
whitespace_before_args=SimpleWhitespace(
value='',
),
),
operator=Or(
whitespace_before=SimpleWhitespace(
value=' ',
),
whitespace_after=SimpleWhitespace(
value=' ',
),
),
right=Call(
func=Name(
value='tes',
lpar=[],
rpar=[],
),
args=[
Arg(
value=SimpleString(
value="'bcd'",
lpar=[],
rpar=[],
),
keyword=None,
equal=MaybeSentinel.DEFAULT,
comma=MaybeSentinel.DEFAULT,
star='',
whitespace_after_star=SimpleWhitespace(
value='',
),
whitespace_after_arg=SimpleWhitespace(
value='',
),
),
],
lpar=[],
rpar=[],
whitespace_after_func=SimpleWhitespace(
value='',
),
whitespace_before_args=SimpleWhitespace(
value='',
),
),
lpar=[],
rpar=[],
),
operator=Or(
whitespace_before=SimpleWhitespace(
value=' ',
),
whitespace_after=SimpleWhitespace(
value=' ',
),
),
right=Call(
func=Name(
value='te',
lpar=[],
rpar=[],
),
args=[
Arg(
value=SimpleString(
value="'cde'",
lpar=[],
rpar=[],
),
keyword=None,
equal=MaybeSentinel.DEFAULT,
comma=MaybeSentinel.DEFAULT,
star='',
whitespace_after_star=SimpleWhitespace(
value='',
),
whitespace_after_arg=SimpleWhitespace(
value='',
),
),
],
lpar=[],
rpar=[],
whitespace_after_func=SimpleWhitespace(
value='',
),
whitespace_before_args=SimpleWhitespace(
value='',
),
),
lpar=[
LeftParen(
whitespace_after=SimpleWhitespace(
value='',
),
),
],
rpar=[
RightParen(
whitespace_before=SimpleWhitespace(
value='',
),
),
],
),
operator=And(
whitespace_before=SimpleWhitespace(
value=' ',
),
whitespace_after=SimpleWhitespace(
value=' ',
),
),
right=BooleanOperation(
left=BooleanOperation(
left=Call(
func=Name(
value='test',
lpar=[],
rpar=[],
),
args=[
Arg(
value=SimpleString(
value="'efg'",
lpar=[],
rpar=[],
),
keyword=None,
equal=MaybeSentinel.DEFAULT,
comma=MaybeSentinel.DEFAULT,
star='',
whitespace_after_star=SimpleWhitespace(
value='',
),
whitespace_after_arg=SimpleWhitespace(
value='',
),
),
],
lpar=[],
rpar=[],
whitespace_after_func=SimpleWhitespace(
value='',
),
whitespace_before_args=SimpleWhitespace(
value='',
),
),
operator=Or(
whitespace_before=SimpleWhitespace(
value=' ',
),
whitespace_after=SimpleWhitespace(
value=' ',
),
),
right=Call(
func=Name(
value='tes',
lpar=[],
rpar=[],
),
args=[
Arg(
value=SimpleString(
value="'fgh'",
lpar=[],
rpar=[],
),
keyword=None,
equal=MaybeSentinel.DEFAULT,
comma=MaybeSentinel.DEFAULT,
star='',
whitespace_after_star=SimpleWhitespace(
value='',
),
whitespace_after_arg=SimpleWhitespace(
value='',
),
),
],
lpar=[],
rpar=[],
whitespace_after_func=SimpleWhitespace(
value='',
),
whitespace_before_args=SimpleWhitespace(
value='',
),
),
lpar=[],
rpar=[],
),
operator=Or(
whitespace_before=SimpleWhitespace(
value=' ',
),
whitespace_after=SimpleWhitespace(
value=' ',
),
),
right=Call(
func=Name(
value='te',
lpar=[],
rpar=[],
),
args=[
Arg(
value=SimpleString(
value="'ghi'",
lpar=[],
rpar=[],
),
keyword=None,
equal=MaybeSentinel.DEFAULT,
comma=MaybeSentinel.DEFAULT,
star='',
whitespace_after_star=SimpleWhitespace(
value='',
),
whitespace_after_arg=SimpleWhitespace(
value='',
),
),
],
lpar=[],
rpar=[],
whitespace_after_func=SimpleWhitespace(
value='',
),
whitespace_before_args=SimpleWhitespace(
value='',
),
),
lpar=[
LeftParen(
whitespace_after=SimpleWhitespace(
value='',
),
),
],
rpar=[
RightParen(
whitespace_before=SimpleWhitespace(
value='',
),
),
],
),
lpar=[],
rpar=[],
)