正则表达式求助:按字符拆分但保留函数表达式不被拆分
解决正则拆分时误拆函数内部括号的问题
我明白你的困扰:用[() ]作为分隔符拆分表达式时,会把currentyear('yyy')里的括号也当成分隔符,导致函数被拆成零散的片段。要解决这个问题,我们需要区分表达式的分组括号和函数内部的括号,不能一概而论地把所有括号都当作分隔符。
下面给你两种实用的解决方案:
方案1:先匹配完整项(推荐)
这种思路是先把需要保留的完整项(比如函数调用、操作数、运算符)都匹配出来,而不是用分隔符拆分。这样能完美避免拆分函数内部的结构。
正则表达式
\w+\([^)]+\)|[^\s()]+
这个正则的逻辑是:
\w+\([^)]+\):匹配完整的函数调用——先匹配函数名(字母数字下划线组成的\w+),再匹配左括号,接着匹配除右括号外的所有内容(函数参数),最后匹配右括号。|:或者的意思[^\s()]+:匹配除空格、左括号、右括号之外的任意连续字符,比如1+2、eq、and这些项。
示例代码(Python)
import re # 你的原始表达式 expr = "((1+2 eq 3) and (2+5 eq 6) or currentyear('yyy') eq '2017')" # 编译正则 pattern = re.compile(r'\w+\([^)]+\)|[^\s()]+') # 提取所有完整项 result = pattern.findall(expr) # 如果还需要把类似1+2的项拆成单个数字和运算符(比如得到1、+、2),可以加这一步 final_result = [] for item in result: if '(' not in item: # 拆分数字、字母运算符、加号 sub_items = re.findall(r'\d+|[a-zA-Z]+|\+', item) final_result.extend(sub_items) else: final_result.append(item) print(final_result)
运行后会得到你想要的结果:['1', '+', '2', 'eq', '3', 'and', '2', '+', '5', 'eq', '6', 'or', "currentyear('yyy')", 'eq', "'2017'"]
如果需要去掉'2017'的引号,只需对该项做strip("'")处理即可。
方案2:用零宽断言精准拆分分隔符
如果你更倾向于用split方法拆分,可以用零宽断言指定只在表达式的分组括号或空格处拆分,排除函数内部的括号。
正则表达式
(?<!\w)\(|\)(?!\w)|\s
这个正则的逻辑是:
(?<!\w)\(:匹配左括号,但要求左括号前面不是字母(也就是排除函数名后面的左括号,比如currentyear(里的()\)(?!\w):匹配右括号,但要求右括号后面不是字母(排除函数内部的右括号)|\s:或者匹配空格作为分隔符
示例代码(Python)
import re expr = "((1+2 eq 3) and (2+5 eq 6) or currentyear('yyy') eq '2017')" # 按指定分隔符拆分 result = re.split(r'(?<!\w)\(|\)(?!\w)|\s', expr) # 过滤拆分后产生的空字符串 result = [item for item in result if item] print(result)
运行结果:['1+2', 'eq', '3', 'and', '2+5', 'eq', '6', 'or', "currentyear('yyy')", 'eq', "'2017'"]
这两种方案都能解决你拆分时误拆函数的问题,你可以根据自己的实际需求选择其中一种。
内容的提问来源于stack exchange,提问作者Anil Bachola
相关产品推荐
相关产品推荐

