如何操作字符串,以便在数学表达式中显式地进行隐式乘法运算


How to manipulate a string so I can make implicit multiplication explicit in a math expression?

我想操作像"…4+3(4-2)-...."这样的字符串成为"…4+3*(4-2)-....",但当然它应该识别任何数字, d,后面跟着一个'('并将其更改为'd*('。如果可能的话,我还想同时将')('改为')*('。如果有可能添加对pi或e等常量的支持,那就太好了。

现在,我只是这样做:

private function make_implicit_multiplication_explicit($string)
{
    $i=1;
    if(strlen($string)>1)
    {
        while(($i=strpos($string,"(",$i))!==false)
        {
            if(strpos("0123456789",substr($string,$i-1,1))) 
            {
                $string=substr_replace($string,"*(",$i,1);
                $i++;
            }
            $i++;
        }
        $string=str_replace(")(",")*(",$string);
    }        
    return $string;
 }

但我相信这可以做得更好与preg_replace或其他一些正则表达式函数?但是我觉得那些手册实在是太麻烦了。

让我们从你要找的开始:

  • 以下任意一个:((a|b)将匹配ab)
    • 任意数字,'d
    • 字符): ')
  • (: '(
  • 创建这个模式:('d|'))'(。但是由于您想修改字符串并保留这两个部分,您可以将'(分组,这导致('()使其更难以读取,但更易于处理。

    现在剩下的一切都是告诉如何重新排列,这很简单:''1*''2,留下这样的代码

    $regex = "/('d|'))('()/";
    $replace = "''1*''2";
    $new = preg_replace($regex, $replace, $test);
    

    要查看模式实际上匹配所有情况,请参见以下示例:

    要识别任何后跟( )(的组合并在它们之间放置星号,您可以使用look - around断言的组合。

    echo preg_replace("/
             (?<=[0-9)])   # look behind to see if there is: '0' to '9', ')'
             (?='()        # look ahead to see if there is: '('
             /x", '*', '(4+3(4-2)-3)(2+3)'); 
    

    Positive Lookbehind断言前面的是数字或右括号。而正向向前看则断言前面的字符后跟一个左括号。

    另一个选择是使用'K转义序列来代替Lookbehind。'K重置上报匹配的起始点。任何先前消耗的字符都不再包括在内(将丢弃到此为止匹配的所有内容)。

    )
    echo preg_replace("/
             [0-9)]   # any character of: '0' to '9', ')'
              'K      # resets the starting point of the reported match
              (?='()  # look ahead to see if there is: '('
             /x", '*', '(4+3(4-2)-3)(2+3)'); 
    

    你的php代码应该是,

    <?php
    $mystring = "4+3(4-2)-(5)(3)";
    $regex = '~'d+'K'(~';
    $replacement = "*(";
    $str = preg_replace($regex, $replacement, $mystring);
    $regex1 = '~')'K'(~';
    $replacement1 = "*(";
    echo preg_replace($regex1, $replacement1, $str);
    ?> //=>  4+3*(4-2)-(5)*(3)
    

    解释:

    • ~'d+'K'(~这将匹配后跟(的一个或多个数字。因为'K,它排除了'd+
    • 再次将匹配的部分替换为*(,进而产生3*(,结果存储在另一个变量中。
    • ')'K'(匹配)(,不包括第一个)。这将被*(所取代,进而产生)*(
    演示1

    演示2

    愚蠢的方法:^)

    $value = '4+3(4-2)(1+2)';
    $search = ['1(', '2(', '3(', '4(', '5(', '6(', '7(', '8(', '9(', '0(', ')('];
    $replace = ['1*(', '2*(', '3*(', '4*(', '5*(', '6*(', '7*(', '8*(', '9*(', '0*(', ')*('];
    echo str_replace($search, $replace, $value);