2010-08-09 88 views
13

我想創建一個Python函數,可以採取簡單的英文描述的正則表達式並返回正則表達式給調用者。是否需要更正式表達正則表達式的聲明方式? :)

當前我正在考慮YAML格式的描述。 因此,我們可以將描述存儲爲一個原始字符串變量,將其傳遞給另一個函數,然後將該函數的輸出傳遞給're'模塊。下面是一個比較簡單的例子:

# a(b|c)d+e* 
re1 = """ 
- literal: 'a' 
- one_of: 'b,c' 
- one_or_more_of: 'd' 
- zero_or_more_of: 'e' 
""" 
myre = re.compile(getRegex(re1)) 
myre.search(...) 

有誰想到這種事情會更廣泛地使用? 你知道現有的軟件包可以做到嗎? 您看到這種方法的侷限性是什麼? 有人認爲,在代碼中使用聲明性字符串會使其更易於維護嗎?

+0

JSON或XML可能? DTD或XSD也可以很好地描述數據結構。 – codymanix 2010-08-09 11:26:23

+7

所以,不是一個複雜的正則表達式需要一整行,而是需要一整個頁面:) – 2010-08-09 11:47:55

+4

知道正則表達式的人對它感到滿意,但對其他人來說,它看起來像字母表扔了。這可能是一個問題,但我不確定。畢竟,對於那些編程的人而言,你可以對編程語言說同樣的話。 它可能是很好的與對象和函數instad字符串,但我不知道什麼是最好的方式來實現的。 +1的創新都一樣。 – psicopoo 2010-08-09 11:49:52

回答

2

對於開發人員嘗試寫正則表達式,很容易去討論和維護,我想知道這種方法是否會提供re.VERBOSE沒有提供的東西。

對於初學者,您的想法可能會有一些吸引力。然而,在你走下這條路之前,你可能會嘗試使用捕獲組,錨點,預見性斷言等來模擬更復雜的正則表達式的聲明語法。一個挑戰是你可能最終得到一個與正則表達式語言一樣難以記住的聲明式語法。

您可能還會考慮其他表達方式。例如,我想到的第一個想法是使用簡短易記名稱的函數表達正則表達式。例如:

from refunc import * 

pattern = Compile(
    'a', 
    Capture(
     Choices('b', 'c'), 
     N_of('d', 1, Infin()), 
     N_of('e', 0, Infin()), 
    ), 
    Look_ahead('foo'), 
) 

但是,當我看到在行動中,它對我來說看起來像一個痛苦。有很多直觀的正則表達式的方面 - 例如,+表示「一個或多個」。一種選擇是混合方法,允許用戶將已經很簡單的那些正則表達式的部分與更深奧的位的函數混合在一起。

pattern = Compile(
    'a', 
    Capture(
     '[bc]', 
     'd+', 
     'e*', 
    ), 
    Look_ahead('foo'), 
) 

我想補充說的是,根據我的經驗,正則表達式是關於學習思維過程的。熟悉語法是很容易的部分。

6

這實際上與詞法分析器/解析器的工作方式非常相似(相同?)。如果你有一個明確的語法,那麼你可以編寫一個解析器而不會有太多的麻煩。例如,你可以寫這樣的東西:

<expression> :: == <rule> | <rule> <expression> | <rule> " followed by " <expression> 
<rule>  :: == <val> | <qty> <val> 
<qty>  :: == "literal" | "one" | "one of" | "one or more of" | "zero or more of" 
<val>  :: == "a" | "b" | "c" | "d" | ... | "Z" | 

這遠不是一個完美的描述。欲瞭解更多信息,請看this BNF of the regex language。然後你可以看看lexingparsing的表達式。

如果你這樣做,你可能會更接近Natural Language /英文版的正則表達式。


我可以看到像這樣的工具很有用,但正如之前所說,主要面向初學者。 這種方法的主要侷限性在於需要編寫的代碼將語言翻譯爲正則表達式(和/或反之亦然)。另一方面,我認爲雙向翻譯工具實際上會更理想,並且會有更多的用途。能夠採用正則表達式並將其轉換爲英文可能會更有助於發現錯誤。

當然,拾取正則表達式並不需要太長的時間,因爲語法通常是簡潔的,大部分的含義都是非常明顯的,至少如果你使用|或||作爲OR用你的語言,你認爲*乘以0-N,+乘以0-N。

雖然有時候我也不會介意鍵入「找到一個或多個‘A’後面的三個數字或‘B’,那麼‘C’」

+0

在回答你的問題時,能夠採用正則表達式並將其轉換爲英文可能會更有助於發現錯誤。在repl模式下使用Python的re.DEBUG參數。 – Daenyth 2010-08-09 21:21:57

+0

@Daenyth - 我意識到這種模式,雖然我沒有理由使用它,但我不能說它比原始正則表達式好得多,除非它是一個非常複雜的正則表達式。 – 2010-08-09 22:11:03

6

請看一看pyparsing。你用RE描述的許多問題都與那些激勵我編寫該程序包的問題相同。

以下是O'Reilly電子書章節"What's so special about pyparsing?"中pyparsing的一些特定功能。

+1

你打敗了我一秒!順便說一句,感謝您編寫pyparsing :) – 2010-08-09 13:06:16

2

你所要求的,也許不完全是,但有一種方法如何寫正則表達式更可讀的方式(VERBOSE,不久X標誌):

rex_name = re.compile(""" 
    [A-Za-z] # first letter 
    [a-z]+  # the rest 
""", re.X) 

rex_name.match('Joe') 
相關問題