Search code examples
phpregexlatexparentheses

PHP - latex format of function with regex


Is it possible to write a regex which would take input like 'sqrt(2 * (2+2)) + sin(pi/6)' and transform it into '\sqrt{2 \cdot (2+2)} + \sin(\pi/6)'?

The problem is the 'sqrt' and parentheses in it. It is obvious I can't simply use something like this:

/sqrt\((.?)\)/ -> \\sqrt{$1}

because this code would create something like this '\sqrt{2 \cdot (2+2)) + \sin(\pi/6}'.


Solution

  • My solution: it simply go throw the string converted to char array and tests if a current substring starts with $latex, if it does second for-cycle go from this point in different direction and by parentheses decides where the function starts and ends. (startsWith function)

    Code:

    public static function formatFunction($function, $latex, $input) {
        $input = preg_replace("/" . $function . "\(/", $latex . "{", $input);
        $arr = str_split($input);
    
        $inGap = false;
        $gap = 0;
    
        for ($i = count($arr) - 1; $i >= 0; $i--) {
            if (startsWith(substr($input, $i), $latex)) {
                for ($x = $i; $x < count($arr); $x++) {
                    if ($arr[$x] == "(" || $arr[$x] == "{") { $gap++; $inGap = true; } 
                    else if ($arr[$x] == ")" || $arr[$x] == "}") {  $gap--; }
    
                    if ($inGap && $gap == 0) {
                        $arr[$x] = "}";
                        $inGap = false;
                        break;
                    }
                }
            }
            $gap = 0;
        }
    
        return implode($arr);
    }
    

    Use:

    self::formatFunction("sqrt", "\\sqrt", 
    "sqrt(25 + sqrt(16 - sqrt(49)) + (7 + 1)) + sin(pi/2)");
    

    Output:

    \sqrt{25+\sqrt{16-\sqrt{49}}+(7+1)}+\sin (\pi/2)
    

    Note: sin and pi aren't formated by this code, it's only str_replace function...