Excel:在“kx + m”文本string中查找k和m

有没有一种巧妙的方法使用VBA或公式在kx+m string查找“k”和“m”variables?

kx + mstring看起来有几种情况,例如:

 312*x+12 12+x*2 -4-x 

等等。 我很确定我可以通过在Excel中编写非常复杂的公式来解决这个问题,但是我想也许有人已经解决了这个问题和类似的问题。 这是我迄今为止最好的,但它不处理所有情况(例如,当kx + mstring中有两个minuses:

=TRIM(IF(NOT(ISERROR(SEARCH("~+";F5))); IF(SEARCH("~+";F5)>SEARCH("~*";F5);RIGHT(F5;LEN(F5)-SEARCH("~+";F5));LEFT(F5;SEARCH("~+";F5)-1)); IF(NOT(ISERROR(SEARCH("~-";F5))); IF(SEARCH("~-";F5)>SEARCH("~*";F5);RIGHT(F5;LEN(F5)-SEARCH("~-";F5)+1);LEFT(F5;SEARCH("~*";F5)-1));"")))

我相信这会帮助你:)

把这个function放在一个模块里:

 Function FindKXPlusM(ByVal str As String) As String Dim K As String, M As String Dim regex As Object, matches As Object, sm As Object '' remove unwanted spaces from input string (if any) str = Replace(str, " ", "") '' create an instance of RegEx object. '' I'm using late binding here, but you can use early binding too. Set regex = CreateObject("VBScript.RegExp") regex.IgnoreCase = True regex.Global = True '' test for kx+m or xk+m types regex.Pattern = "^(-?\d*)\*?x([\+-]?\d+)?$|^x\*(-?\d+)([\+-]?\d+)?$" Set matches = regex.Execute(str) If matches.Count >= 1 Then Set sm = matches(0).SubMatches K = sm(0) M = sm(1) If K = "" Then K = sm(2) If M = "" Then M = sm(3) If K = "-" Or K = "+" Or K = "" Then K = K & "1" If M = "" Then M = "0" Else '' test for m+kx or m+xk types regex.Pattern = "^(-?\d+)[\+-]x\*([\+-]?\d+)$|^(-?\d+)([\+-]\d*)\*?x$" Set matches = regex.Execute(str) If matches.Count >= 1 Then Set sm = matches(0).SubMatches M = sm(0) K = sm(1) If M = "" Then M = sm(2) If K = "" Then K = sm(3) If K = "-" Or K = "+" Or K = "" Then K = K & "1" If M = "" Then M = "0" End If End If K = Replace(K, "+", "") M = Replace(M, "+", "") '' the values found are in K & M. '' I output here in this format only for showing sample. FindKXPlusM = " K = " & K & " M = " & M End Function 

然后你可以从macros中调用它,例如:

 Sub Test() Debug.Print FindKXPlusM("x*312+12") End Sub 

或者像公式一样使用它。 例如把它放在一个单元格中:

 =FindKXPlusM(B1) 

我喜欢第二种方式(less工作:P)

我testing了不同的值,这里是我得到的一个截图:

查找KX + M公式的屏幕截图

希望这可以帮助 :)

而不是麻烦parsing在VBA中运行一个简单的LINEST

根据需要replaceStrFunc

 Sub Extract() Dim strFunc As String Dim X(1 To 2) As Variant Dim Y(1 To 2) As Variant Dim C As Variant X(1) = 0 X(2) = 100 strFunc = "312*x+12" 'strFunc = "12+x*2 " 'strFunc = "-4-X" Y(1) = Evaluate(Replace(LCase$(strFunc), "x", X(1))) Y(2) = Evaluate(Replace(LCase$(strFunc), "x", X(2))) C = Application.WorksheetFunction.LinEst(Y, X) MsgBox "K is " & C(1) & vbNewLine & "M is " & C(2) End Sub 

这看起来比较复杂。 如果我没有错,一个kx + m可以有最多7个操作符和最less1个操作符。 在这种情况下,获得“K”和“M”值变得非常复杂。 – Siddharth Rout 33分钟前

根据我在duffymo的post中的评论

此快照显示“kx + m”可以具有的不同组合

在这里输入图像描述

如前所述,实现你想要的是非常复杂的。 这是我目前提取“ K ”的微弱尝试这段代码在任何方面都不是优雅的 :(另外我还没有testing过不同场景的代码,所以它可能会失败,但是如何解决这个问题会给你一个公平的想法,你将不得不调整它得到你想要的确切结果。

代码 (我正在testing这个代码中的7种可能的组合,它适用于这7个,但可能会失败)

 Option Explicit Sub Sample() Dim StrCheck As String Dim posStar As Long, posBrk As Long, pos As Long, i As Long Dim strK As String, strM As String Dim MyArray(6) As String MyArray(0) = "-k*(-x)+(-m)*(-2)" MyArray(1) = "-k*x+(-m)*(-2)" MyArray(2) = "-k(x)+(-m)*(-2)" MyArray(3) = "-k(x)+(-m)(-2)" MyArray(4) = "-kx+m" MyArray(5) = "kx+m" MyArray(6) = "k(x)+m" For i = 0 To 6 StrCheck = MyArray(i) Select Case Left(Trim(StrCheck), 1) Case "+", "-" posBrk = InStr(2, StrCheck, "(") posStar = InStr(2, StrCheck, "*") If posBrk > posStar Then '<~~ "-k*(-x)+(-m)*(-2)" pos = InStr(2, StrCheck, "*") If pos <> 0 Then strK = Mid(StrCheck, 1, pos - 1) Else strK = Mid(StrCheck, 1, posBrk - 1) End If ElseIf posBrk < posStar Then '<~~ "-k(-x)+(-m)*(-2)" pos = InStr(2, StrCheck, "(") strK = Mid(StrCheck, 1, pos - 1) Else '<~~ "-kx+m" '~~> In such a case I am assuming that you will never use '~~> a >=2 letter variable strK = Mid(StrCheck, 1, 2) End If Case Else posBrk = InStr(1, StrCheck, "(") posStar = InStr(1, StrCheck, "*") If posBrk > posStar Then '<~~ "k*(-x)+(-m)*(-2)" pos = InStr(1, StrCheck, "*") If pos <> 0 Then strK = Mid(StrCheck, 1, pos - 2) Else strK = Mid(StrCheck, 1, posBrk - 1) End If ElseIf posBrk < posStar Then '<~~ "k(-x)+(-m)*(-2)" pos = InStr(1, StrCheck, "(") strK = Mid(StrCheck, 1, pos - 2) Else '<~~ "kx+m" '~~> In such a case I am assuming that you will never use '~~> a >=2 letter variable strK = Mid(StrCheck, 1, 1) End If End Select Debug.Print "Found " & strK & " in " & MyArray(i) Next i End Sub 

快照

在这里输入图像描述

这不是很多,但我希望这能让你走上正确的道路

我会使用正则expression式来search一个或多个数字; m之后的“* x”和k之后的“+”之后。

你的例子显示整数值。 如果斜率和截距是浮点数呢? 签名的值? 这比你的例子提出的要复杂得多。

我build议最通用的解决scheme是用一个简单的语法编写一个词法分析器来解决这个问题。 我不知道VB或.NET为你提供什么。 ANTLR将在Java-land上提供一个解决scheme; 有一个ANTLR.NET。

我不确定所有这些努力都会给你带来什么。 你将如何处理提取的内容? 我认为用户可以很容易地为k和m填充数字types的单元格,并从这些单元格中计算y = m*x + k ,而不是插入一个string并提取它们。

如果你的目标只是评估一个string,也许eval()是你的答案:

如何把一个string公式转换成一个“真实”的公式