使用sed正则表达式为数学表达式添加圆括号的技术咨询
用sed为连续加法运算添加括号的解决方案
一、普通场景:纯数字连续加法块加括号
针对86 * 21 + 7 * 13 * 31 + 26 + 31 * 5这类纯数字组成的加法序列被乘法分隔的场景,我们可以通过匹配整个连续加法块而非两两数字来实现一次性加括号。
实现命令
使用扩展正则(-E选项避免大量转义),结合三个替换规则覆盖开头、中间、结尾的加法块:
sed -E ' # 处理开头的加法块(如 "21 +7 * 13" → "(21 +7) * 13") s/^([0-9]+(\s*\+\s*[0-9]+)+)\s*\*/(\1) */; # 处理结尾的加法块(如 "13 * 21 +7" → "13 * (21 +7)") s/\*\s*([0-9]+(\s*\+\s*[0-9]+)+)$/* (\1)/; # 处理中间被乘法包围的加法块 s/\*\s*([0-9]+(\s*\+\s*[0-9]+)+)\s*\*/ * (\1) */g ' expr.txt
效果验证
原表达式:86 * 21 + 7 * 13 * 31 + 26 + 31 * 5
处理后:86 * (21 + 7) * 13 * (31 + 26 + 31) * 5
规则说明
[0-9]+(\s*\+\s*[0-9]+)+:匹配一个数字开头,后面跟**一个或多个+数字**的连续加法序列,确保整个加法块被一次性选中。- 三个规则分别覆盖加法块在表达式开头、结尾、中间(被乘法分隔)的三种情况。
二、特殊场景:含嵌套括号的连续加法嵌套加括号
针对23 + (2 * 53) + (34 * 66) * 55这类包含嵌套括号、且整个加法序列作为乘法左操作数的场景,需要通过循环替换实现左结合的嵌套括号。
实现命令
sed -E ' :loop # 循环替换最左侧的两个加法项,包裹成括号 s/^([^+]+)\s*\+\s*([^+]+)\s*\+/(\1 + \2) +/ # 如果替换成功,回到loop继续处理 t loop # 最后将整个加法序列包裹成括号,作为乘法左操作数 s/^([^*]+)\s*\*/(\1) */ ' expr.txt
效果验证
原表达式:23 + (2 * 53) + (34 * 66) * 55
处理后:((23 + (2 * 53)) + (34 * 66)) * 55
规则说明
:loop和t loop:sed的循环语法,只要替换成功就重复执行,直到没有可替换的相邻加法项。^([^+]+)\s*\+\s*([^+]+)\s*\+:匹配行首的两个相邻加法项(允许项内包含括号),将其包裹成括号,逐步实现左嵌套。- 最后一步替换将剩余的整个加法序列包裹,确保它作为一个整体参与乘法运算。
三、注意事项
- sed的正则不支持递归匹配复杂嵌套括号,如果你的表达式包含多层嵌套(如
A + (B + (C + D)) * E),上述命令可能需要调整。 - 若要同时处理两种场景,可以将两组命令合并,先处理纯数字加法块,再处理含嵌套括号的情况。
- 如果表达式复杂度很高(如混合加减乘除、多层嵌套),建议使用更专业的工具(如Perl、Python的表达式解析库),避免正则的局限性。
内容的提问来源于stack exchange,提问作者Develobeer
相关产品推荐
相关产品推荐

