簡體   English   中英

為什么我的正則表達式會為字符串中的每個字符返回元組?

[英]Why does my regular expression return tuples for every character in a string?

我正在為我的數學 class 制作一個簡單的項目,我想在其中驗證給定的 function 主體(字符串)是否僅包含允許的表達式(數字、基本三角函數、+、-、*、/)。 我正在使用帶有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 個空字符串的元組列表: ('', '', '')對於字符串中的每個字符,除非存在觸發 function在這種情況下,它將返回一個帶有觸發器 function 和兩個空字符串的元組。

例如:cos(x) -> [('cos', '', ''), ('', '', ''), ('', '', ''), ('', '', '')]

我不明白為什么會這樣,我已經在regexr.com上測試了正則表達式,它工作正常。 我知道它使用 javascript 但通常應該沒有區別吧?

感謝您的任何解釋和/或修復。

簡短的回答:如果你想要的結果是['cos', '(', 'x', ')'] ,你需要類似'(cos|sin|tan|[)(-*x]|\d+)' :

>>> re.findall(r'(cos|sin|tan|[)(-*x]|\d+)', "cos(x)")
['cos', '(', 'x', ')']

findall的文檔中:

結果取決於模式中捕獲組的數量。 如果沒有組,則返回與整個模式匹配的字符串列表。 如果只有一個組,則返回與該組匹配的字符串列表。 如果存在多個組,則返回與組匹配的字符串元組列表。 非捕獲組不影響結果的形式。

對於'cos(x)' ,您從('cos', '', '')開始,因為cos匹配,但sintan都不匹配。 對於(x)中的每一個,三個捕獲組都沒有匹配,盡管括號表達式匹配。 由於它不在捕獲組內,因此它匹配的任何內容都不包含在您的 output 中。

順便說一句, [\d+/*x)(-]不包括多位整數作為匹配項。 \d+不是正則表達式;它是兩個字符d+ 。(轉義是空操作,因為d[...]中沒有特殊含義。)因此,它與以下八個字符之一完全匹配:

  1. d
  2. +
  3. /
  4. *
  5. x
  6. )
  7. (
  8. -

您的正則表達式中有三個組(一個帶括號的表達式),因此您得到包含三個項目的元組。 此外,您會得到與您的正則表達式匹配的所有子字符串的四個結果:第一個是“cos”,第二個是“(”,第三個是“x”,最后一個是“)”。 但是你的正則表達式的最后一部分沒有標記為一個組,所以你沒有在你的元組中得到這個匹配。 如果您像 r"(cos)|(sin)|(tan)|([\d+/*x)(-])" 更改您的正則表達式,您將獲得包含四個項目的元組。 每個元組都有一個非空項。

不幸的是,此修復程序無法幫助您驗證您沒有被禁止的詞位。 這只是為了了解發生了什么。

我建議您將您的正則表達式轉換為否定形式:您可以檢查除了允許的詞位之外什么都沒有,而不是檢查您是否有一些允許的詞位。 我想這種方式應該適用於簡單的情況。 但是,恐怕,對於更復雜的表達,你必須使用正則表達式以外的東西。

findall 返回元組,因為您的正則表達式具有捕獲組。 要使組不捕獲,請在左括號后添加?: ::

r"(?:cos)|(?:sin)|(?:tan)|[\d+/*x)(-]"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM