我正在為我的數學課制作一個簡單的專案,我想在其中驗證給定的函式體(字串)是否僅包含允許的運算式(數字、基本三角函式、 、-、*、/)。我在該re.findall方法中使用正則運算式。我當前的代碼:
import re
def valid_expression(exp) -> bool:
# remove white spaces
exp = exp.replace(" ", "")
# characters to search for
chars = r"(cos)|(sin)|(tan)|[\d /*x)(-]"
z = re.findall(chars, exp)
return "".join(z) == exp
但是,當我測驗這個任何運算式時,re.findall(chars, exp)它將回傳一個帶有 3 個空字串的元組串列:('', '', '')對于字串中的每個字符,除非有一個 trig 函式,在這種情況下它將回傳一個帶有 trig 函式和兩個空字串的元組。
例如:cos(x) -> [('cos', '', ''), ('', '', ''), ('', '', ''), ('', '', '')]
我不明白為什么會這樣,我已經在regexr.com上測驗了正則運算式,它作業正常。我知道它使用 javascript 但通常應該沒有區別吧?
感謝您的任何解釋和/或修復。
uj5u.com熱心網友回復:
簡短的回答:如果你想要的結果是['cos', '(', 'x', ')'],你需要類似
'(cos|sin|tan|[)(-*x]|\d )':
>>> re.findall(r'(cos|sin|tan|[)(-*x]|\d )', "cos(x)")
['cos', '(', 'x', ')']
從檔案中findall:
結果取決于模式中捕獲組的數量。如果沒有組,則回傳與整個模式匹配的字串串列。如果只有一個組,則回傳與該組匹配的字串串列。如果存在多個組,則回傳與組匹配的字串元組串列。非捕獲組不影響結果的形式。
對于'cos(x)',您從('cos', '', '')因為cos匹配開始,但既不匹配sin也不tan匹配。對于 、 和 中的每一個(,x三個)捕獲組都不匹配,盡管括號運算式匹配。由于它不在捕獲組內,因此它匹配的任何內容都不會包含在您的輸出中。
順便說一句,[\d /*x)(-]不包括多位整數作為匹配項。\d 不是正則運算式;這是兩個字符d和 。(轉義是無操作的,因為d在 內部沒有特殊含義[...]。)結果,它完全匹配以下八個字符之一:
d/*x)(-
uj5u.com熱心網友回復:
您的正則運算式中有三個組(一個帶括號的運算式),因此您得到包含三個專案的元組。此外,您會得到與您的正則運算式匹配的所有子字串的四個結果:第一個是“cos”,第二個是“(”,第三個是“x”,最后一個是“)”。但是你的正則運算式的最后一部分沒有標記為一個組,所以你沒有在你的元組中得到這個匹配。如果您像 r"(cos)|(sin)|(tan)|([\d /*x)(-])" 更改您的正則運算式,您將獲得包含四個專案的元組。每個元組都有一個非空項。
不幸的是,此修復程式無法幫助您驗證您沒有被禁止的詞位。這只是為了了解發生了什么。
我建議您將您的正則運算式轉換為否定形式:您可以檢查除了允許的詞位之外什么都沒有,而不是檢查您是否有一些允許的詞位。我想這種方式應該適用于簡單的情況。但是,恐怕,對于更復雜的表達,你必須使用正則運算式以外的東西。
uj5u.com熱心網友回復:
findall 回傳元組,因為您的正則運算式具有捕獲組。要使組不捕獲,?:請在左括號后添加:
r"(?:cos)|(?:sin)|(?:tan)|[\d /*x)(-]"
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/411337.html
標籤:
