2012-10-02 220 views
3

所以我有一个快速的问题,我无法弄清楚。正则表达式捕获组

我有,我想分析例如一些线路:

  • a = a/2;
  • b*= a/4*2;
  • float c += 4*2*sin(2);

而且我要的是得到的分配变量名分配。所以,在这种情况下,我希望检索a,b,c

我有以下的正则表达式:

match = re.search(r'\b(?:float)?(.*)(?:(\+|-|\*|\\)? =)',line) 

当我打印出来m.group(1)它将返回ab *c +

我不明白为什么它还捕获=之前的操作员,有人可以解释吗?

回答

2

你有一个前面的贪婪捕获与(.*),你可以让你的操作员捕获是可选的(与结尾?);有了这个,贪婪捕获就是引入运营商,而不是让它落入匹配=的组。

尝试将贪婪捕获更改为只有那里可以接受。从外观上来看,它只能是字母数字值和空间(数字是一个猜测,所以,如果没有必要,可能被丢弃):

\b(?:float\s+)?([a-zA-Z0-9]+)\s*(?:(\+|-|\*|\\)? =) 
+1

或者只是使用一个非贪婪的捕获,那么你不需要猜测什么字符是允许的。 – interjay

+1

sry但非贪婪的捕获看起来像什么? – overloading

+1

是这样的:'(。*?)' –

0

我认为这可能是一个更简单的正则表达式。

首先,你的变量只能是字母数字,我还没有看到任何其他变量。

所以已经在您的捕获组是这样的:(\w+)

那么,如果能在这之前是一个float,它的确应该看起来像\b(?:float\s+)?

但真正的唯一的事情,这就是我们所需要的。

唯一缺少的是读取到的一次尝试阅读这一切的情况下,该行的末尾,否则,因为它涉及的不是如果你读每一行需要它:.*\n

让你整个事情可以是:\b(?:float\s+)?(\w+).*\n 一旦正则表达式达到非字母数字(例如空格,'='符号或任何其他字符),它将停止成为捕获组的一部分。

:)

运行我在你的例子中提到的正则表达式:

>>> import re 
>>> re.findall(r'\b(?:float\s+)?(\w+).*\n', "a = a/2;\nb*= a/4*2;\nfloat c += 4*2*sin(2);\n") 
['a', 'b', 'c'] 

,并运行在每个时间线:(^告诉正则表达式开始在字符串的开头)

>>> re.findall(r'^(?:float\s+)?(\w+)', "a = a/2") 
['a'] 
>>> re.findall(r'^(?:float\s+)?(\w+)', "b*= a/4*2") 
['b'] 
>>> re.findall(r'^(?:float\s+)?(\w+)', "float c += 4*2*sin(2)") 
['c']