使用正则表达式将Excel公式转换为Wolfram Mathematica

5

我正在导入Excel文件,并提取这些文件中的公式以执行各种测试和计算,这是Excel无法完成的。但是,为了做到这一点,我需要将Excel函数转换为Mathematica可以使用的函数。所有这些公式都非常大(平均200多页),因此手动转换不是一个选项。这就带来了我的当前问题。 我需要转换的某些公式包含Excel函数内的括号,导致出现如下情况:

IF(IF((A2+B2)*(C1+2^D1)<>7,"A","B")="A",C8,D8)*2/IF(G17*G2=G1,IF(EXP(K9)=K10,K11,K12))*EXP(IF(H22+H23=213,A1,B1))

我需要将IF和EXP函数中的所有()转换为[],而不改变像(A2+B2)这样的部分。 目标是将其转换为:

IF[IF[(A2+B2)*(C1+2^D1)<>7,"A","B"]="A",C8,D8]*2/IF[G17*G2=G1,IF[EXP[K9]=K10,K11,K12]]*EXP[IF[(H22+H23)=213,A1,B1]]

有没有正则表达式可以匹配这些情况?

1
请返回相关的翻译内容:https://dev59.com/N2sz5IYBdhLWcg3wcXXF - agentp
你的示例中括号不平衡(左边有9个,右边有8个) - agentp
@高性能马克 Excel之所以可以适应如此大的公式,是因为它被分成了许多单元格。如果有任何变化并且Excel重新计算它,程序会冻结很长时间,这也是我想将其导入Mathematica的原因之一。 我尝试使用以下正则表达式及其变体: (.*?\\(.*?\\)(.?)*?)*?这导致了一些问题,它没有匹配到应该匹配的部分,或者匹配了不应该匹配的东西。 - Soviras
仅供好奇,单个Excel公式显然限制在约8000个字符。 - agentp
显示剩余2条评论
1个回答

5
string = "IF(IF((A2+B2)*(C1+2^D1)<>7,\"A\",\"B\")=\"A\",C8,D8)*2/IF(\
G17*G2=G1,IF(EXP(K9)=K10,K11,K12))*EXP(IF(H22+H23=213,A1,B1))"

这个怎么样?
ClearAll@rectBrackets;

rectBrackets := StringReplace[ #, 
    (f_?UpperCaseQ ~~ fr : LetterCharacter ..) ~~ 
    "(" ~~ Shortest[content__] ~~ ")" /; (
        StringCount[content, ")"] == StringCount[content, "("]
    ) :> (
        f <> ToLowerCase[fr] <> "[" <> rectBrackets @ content <> "]"
    )
] &;

operators = StringReplace[#, {"=" -> "==", "<>" -> "!="}] &;

现在让我们来使用它们:

rectBrackets @ operators @ string
"If[If[(A2+B2)*(C1+2^D1)!=7,\"A\",\"B\"]==\"A\",C8,D8]*2/If[G17*\
G2==G1,If[Exp[K9]==K10,K11,K12]]*Exp[If[H22+H23==213,A1,B1]]"
 ToExpression @ %

enter image description here


@Soviras 很好,但请记住这只是一个非常简单的例子。当您在检查中的字符串内有“(”或“)”时,它可能会失败,因此平衡检查将失败。通常需要更加健壮的模式。但这已经足够好分享了 :) - Kuba

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