2010-10-07 90 views
2

問題您可以使用單個正則表達式來解析函數參數嗎?

有一個程序文件,其中包含以下代碼片段在文件中的某個點。

... 

food($apples$ , $oranges$ , $pears$ , $tomato$){ 
    ... 
} 

... 

此函數可能包含任意數量的參數,但它們必須是用逗號分隔的字符串。所有參數字符串都是小寫字母。

我希望能夠使用正則表達式解析出每個參數。例如,在蟒蛇結果列表將如下所示:

["apples", "oranges", "pears", "tomato"] 

嘗試性解決方案

使用Python RE模塊,我能打破這個問題分成兩個部分來實現這一點。

  1. 查找代碼中的函數並提取參數列表。

    plist = re.search(r'food\((.*)\)', programString).group(1) 
    
  2. 使用另一個正則表達式拆分列表。

    params = re.findall(r'[a-z]+', plist) 
    

問題

反正是有,我可以用一個正則表達式,而不是兩個實現這一目標?

編輯

感謝Tim Pietzcker的答案我能找到一些相關的問題:

  1. Python regular expressions - how to capture multiple groups from a wildcard expression?
  2. Which regex flavors support captures (as opposed to capturing groups)?

回答

2

回答你的問題「是否可以在一個正則表達式中完成?」:是的,但不是Python。

如果您想匹配並捕獲(單獨)未知數量的匹配,如您的示例中所示,只使用一個正則表達式,則需要a regex engine that supports captures (as opposed to capturing groups)。目前只有.NET和Perl 6才能做到這一點。

所以在Python中,你要麼需要做的兩個步驟(find整個food(...)函數調用,然後findall個體與第二正則表達式匹配了巴丁格的建議)。

或者使用像Paul McGuire的pyparsing這樣的解析器。

+0

謝謝你回答所問的問題。 – Nixuz 2010-10-08 07:38:01

0
params = re.findall(r'\$([a-z]+)\$', programString) 
+1

從我可以看到這是行不通的,因爲可能還有其他的功能,有太多的字符串參數列表。我只想從'食物'功能的參數列表。 – Nixuz 2010-10-07 20:56:22

0

事情是這樣的正則表達式應該w ^掃

food\((\$(?<parm>\w+)\$\s*,?\s*)+\).* 

它把所有匹配的參數名稱的「PARM」組

+0

這不只是返回第一個參數嗎? – Nixuz 2010-10-07 21:08:18

+0

不,它應該返回所有在parm組 – CaffGeek 2010-10-07 21:23:16

+1

它只返回最後一個參數 – SilentGhost 2010-10-07 21:23:21

2

Pyparsing是非常方便的這種東西在,當你不知道什麼時候你會遇到額外的空格,評論, 隨你。像在RE命名組,本實施例定義了用於檢索所期望的數據的結果名「參數」:如果我改變所述第二函數到

>>> code = """\ 
... ... 
... 
... food($apples$ , $oranges$ , $pears$ , $tomato$){ 
... ... 
... } 
... ... 
... food($peanuts$, $popcorn$ ,$candybars$ ,$icecream$){ 
... ... 
... } 
... """ 
>>> from pyparsing import * 
>>> LPAR,RPAR,LBRACE,RBRACE,DOLLAR = map(Suppress,"(){}$") 
>>> param = DOLLAR + Word(alphas) + DOLLAR 
>>> funcCall = "food" + LPAR + delimitedList(param)("parameters") + RPAR + LBRACE 
>>> for fn in funcCall.searchString(code): 
... print fn.parameters 
... 
['apples', 'oranges', 'pears', 'tomato'] 
['peanuts', 'popcorn', 'candybars', 'icecream'] 

... food($peanuts$, $popcorn$ ,/*$candybars$ ,*/$icecream$){ 

,然後添加該行:

>>> funcCall.ignore(cStyleComment) 

然後我得到:

>>> for fn in funcCall.searchString(code): 
... print fn.parameters 
... 
['apples', 'oranges', 'pears', 'tomato'] 
['peanuts', 'popcorn', 'icecream'] 
+0

有很多方法可以做我想做的事情;然而,我很好奇它是否可以用一個正則表達式來完成。不管怎麼說,還是要謝謝你。 – Nixuz 2010-10-07 21:11:26

1

爲什麼是正則表達式?

for line in open("file"): 
    line=line.rstrip() 
    if line.lstrip().startswith("food") : 
     for item in line.split(")"): 
      if "food" in item: 
       print item.split("(")[-1].split(",") 

輸出

$ ./python.py 
['$apples$ ', ' $oranges$ ', ' $pears$ ', ' $tomato$']