我正在使用python处理方程。
我想捕捉乘法的重复操作数,如下所示
5*5 --> 5
3.14*4 --> no return
(10-4)*(10-4) --> (10-4)
我找到了单独的模式来解决有或不带括号的场景
pattern = r"(?=(?:\D|\b))(\d+)\*\1(?=(?:\D|\b))"
re.findall(pattern, "15*15") # ['15']
re.findall(pattern, "3.14*4") # []
pattern = r"(\([\d\-\+]+\))\*\1"
re.findall(pattern, "(10-4)*(10-4)") # ['(10-4)']
但我发现,不能通过交替(|
)或?
量化器将这两种模式组合在一起是很棘手的。
pattern = r"(?=(?:\D|\b))(\d+)\*\1(?=(?:\D|\b))|(\([\d\-\+]+\))\*\1" # Alternation
re.findall(pattern, "15*15") # [('15', '')]
re.findall(pattern, "3.14*4") # []
re.findall(pattern, "(10-4)*(10-4)") # []
pattern = r"(?=(?:\D|\b))(\(?[\d\-\+]+\)?)\*\1(?=(?:\D|\b))" # with ? for parenthese
re.findall(pattern, "15*15") # ['15']
re.findall(pattern, "3.14*4") # []
re.findall(pattern, "(10-4)*(10-4)") # []
有什么解决办法吗?或者我应该分开做?
发布于 2020-11-19 09:00:32
您可以使用
(?<!\d)(\d+)\*\1(?!\d)|(\([\d+-]+\))\*\2
见regex演示。详细信息:
(?<!\d)(\d+)\*\1(?!\d)
-任何一个或多个数字(捕获到第1组中)都不以数字括起来,后面跟着一个*
字符,然后是与第1组中相同的数字(不是后面跟着一个数字)。|
-或(\([\d+-]+\))\*\2
-第2组,捕获(
,然后捕获一个或多个数字,-
或+
,然后是)
字符,然后匹配*
字符和与组2中相同的值。在Python中,使用
import re
rx = r"(?<!\d)(\d+)\*\1(?!\d)|(\([\d+-]+\))\*\2"
texts = ["5*5", "3.14*4", "(10-4)*(10-4)"]
for text in texts:
print( [f'{x.group(1) or ""}{x.group(2) or ""}' for x in re.finditer(r'(?<!\d)(\d+)\*\1(?!\d)|(\([\d+-]+\))\*\2', text)] )
见在线Python演示。输出:
['5']
[]
['(10-4)']
发布于 2020-11-19 09:11:58
你可以用
(?<!\d)((\()?\d+(?:[.-]\d+)?(?(2)\)))\*\1(?!\d)
解释
(?<!\d)
不直接向左断言一个数字(
Capture group 1 (\()?
可选择匹配组2中的(
\d+
匹配1+数字(?:[.-]\d+)?
可选择匹配.
或-
和1+数字。(?(2)\))
匹配)
)
闭组1\*\1
匹配*
,后面是在第1组中捕获的反向引用(?!\d)
不直接向右断言一个数字import re
regex = r"(?<!\d)((\()?\d+(?:[.-]\d+)?(?(2)\)))\*\1(?!\d)"
test_str = ("5*5 --> 5 \n"
"3.14*4 --> no return \n"
"(10-4)*(10-4) --> (10-4)")
for m in re.finditer(regex, test_str):
print(m.group(1))
输出
5
(10-4)
https://stackoverflow.com/questions/64908314
复制相似问题