PHP - 正则表达式函数的 Latex 格式
PHP - latex format of function with regex
是否可以编写一个正则表达式来接收像 'sqrt(2 * (2+2)) + sin(pi/6)'
这样的输入并将其转换为 '\sqrt{2 \cdot (2+2)} + \sin(\pi/6)'
?
问题是里面的'sqrt'和括号。很明显我不能简单地使用这样的东西:
/sqrt\((.?)\)/ -> \sqrt{}
因为这段代码会创建这样的东西 '\sqrt{2 \cdot (2+2)) + \sin(\pi/6}'
。
一般来说,no regular expression can effectively handle nested parentheses. Sorry to be the bearer of bad news! The MathJAX 解析器库可以解释 LaTeX 方程,您可以添加自定义输出例程来执行您想要的操作。
TeX题,也可以试试http://tex.stackexchange.com.
前段时间我用这种方法解决了类似的问题。也许对你有帮助
$str = 'sqrt((2 * (2+2)) + sin(pi/(6+7)))';
$from = []; // parentheses content
$to = []; // patterns for replace #<number>
$brackets = [['(', ')'], ['{', '}'], ['[', ']']]; // new parentheses for every level
$level = 0;
$count = 1; // count or replace made
while($count) {
$str = preg_replace_callback('(\(([^()]+)\))',
function ($m) use (&$to, &$from, $brackets, $level) {
array_unshift($to, $brackets[$level][0] . $m[1] . $brackets[$level][1]);
$i = '#' . (count($to)-1); // pattern for future replace.
// here it '#1', '#2'.
// Make it so they will be unique
array_unshift($from, $i);
return $i; }, $str, -1, $count);
$level++;
}
echo str_replace($from, $to, $str); // return content back
// sqrt[{2 * (2+2)} + sin{pi/(6+7)}]
我忘记了所有细节,但它似乎有效
我的解决方案:它只是将字符串转换为 char 数组并测试当前子字符串是否以 $latex
开头,如果它确实从这一点开始以不同的方向进行第二个 for-cycle 并由括号决定函数开始和结束的地方。 (startsWith 函数)
代码:
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);
}
使用:
self::formatFunction("sqrt", "\sqrt",
"sqrt(25 + sqrt(16 - sqrt(49)) + (7 + 1)) + sin(pi/2)");
输出:
\sqrt{25+\sqrt{16-\sqrt{49}}+(7+1)}+\sin (\pi/2)
注意:sin
和pi
不是由这段代码格式化的,它只是str_replace
函数...
是否可以编写一个正则表达式来接收像 'sqrt(2 * (2+2)) + sin(pi/6)'
这样的输入并将其转换为 '\sqrt{2 \cdot (2+2)} + \sin(\pi/6)'
?
问题是里面的'sqrt'和括号。很明显我不能简单地使用这样的东西:
/sqrt\((.?)\)/ -> \sqrt{}
因为这段代码会创建这样的东西 '\sqrt{2 \cdot (2+2)) + \sin(\pi/6}'
。
一般来说,no regular expression can effectively handle nested parentheses. Sorry to be the bearer of bad news! The MathJAX 解析器库可以解释 LaTeX 方程,您可以添加自定义输出例程来执行您想要的操作。
TeX题,也可以试试http://tex.stackexchange.com.
前段时间我用这种方法解决了类似的问题。也许对你有帮助
$str = 'sqrt((2 * (2+2)) + sin(pi/(6+7)))';
$from = []; // parentheses content
$to = []; // patterns for replace #<number>
$brackets = [['(', ')'], ['{', '}'], ['[', ']']]; // new parentheses for every level
$level = 0;
$count = 1; // count or replace made
while($count) {
$str = preg_replace_callback('(\(([^()]+)\))',
function ($m) use (&$to, &$from, $brackets, $level) {
array_unshift($to, $brackets[$level][0] . $m[1] . $brackets[$level][1]);
$i = '#' . (count($to)-1); // pattern for future replace.
// here it '#1', '#2'.
// Make it so they will be unique
array_unshift($from, $i);
return $i; }, $str, -1, $count);
$level++;
}
echo str_replace($from, $to, $str); // return content back
// sqrt[{2 * (2+2)} + sin{pi/(6+7)}]
我忘记了所有细节,但它似乎有效
我的解决方案:它只是将字符串转换为 char 数组并测试当前子字符串是否以 $latex
开头,如果它确实从这一点开始以不同的方向进行第二个 for-cycle 并由括号决定函数开始和结束的地方。 (startsWith 函数)
代码:
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);
}
使用:
self::formatFunction("sqrt", "\sqrt",
"sqrt(25 + sqrt(16 - sqrt(49)) + (7 + 1)) + sin(pi/2)");
输出:
\sqrt{25+\sqrt{16-\sqrt{49}}+(7+1)}+\sin (\pi/2)
注意:sin
和pi
不是由这段代码格式化的,它只是str_replace
函数...