正则表达式捕获组

3

我有一个快速问题,但我无法解决。

我想要解析一些代码行,例如:

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

我想获得赋值的变量名称。 所以,在这种情况下,我想检索abc

我有以下正则表达式:

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

当我打印出m.group(1)时,它会返回ab *c +

我无法理解为什么它还会捕获等于号前的操作符,有人能解释一下吗?

2个回答

2
你在使用(.*)进行贪婪捕获,并且允许你的操作符捕获是可选的(以?结尾);因此,贪婪捕获是带入操作符的那个,而不是让它流到匹配=的组中。
尝试将贪婪捕获更改为仅接受可接受的内容。从外观上看,它只能是字母数字和空格(如果不需要,数字可以省略):
\b(?:float\s+)?([a-zA-Z0-9]+)\s*(?:(\+|-|\*|\\)? =)

1
或者简单地使用非贪婪捕获,这样你就不需要猜测哪些字符是允许的。 - interjay
1
抱歉,非贪婪捕获是什么样子的? - overloading

0

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

首先,您的变量只能是字母数字字符,我还没有见过其他类型的变量。

因此,您的捕获组看起来像这样:(\w+)

然后,如果在变量前面的唯一内容是浮点数,则应该看起来像这样\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']

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接