可以肯定的是,使用两个正则表达式并没有错,另一个答案的preg_match_all() 也可以。另一种方法是将它们捕获到单个数组中,然后将其分成两个。由于我们正在讨论拆分,让我们使用 preg_split() 和 PREG_SPLIT_DELIM_CAPTURE 标志。这会产生一个数字数组,如下所示为您的示例方程:
Array [
[0] => 155
[1] => +
[2] => 44
[3] => x
[4] => 3
[5] => /
[6] => 2
[7] => -
[8] => 12
]
现在,由于您的等式将以数字开头,因此可以相当安全地假设您的所有运算符在结果数组中都有奇数键。然后,我们可以在键上用% 2 == 0 或零模数将它们分开,从而将奇数和偶数分叉到单独的数组中。
$equation = '155+44x3/2-12';
// Use ~\s*(\D)\s*~ if you may have spaces around operators
// Use ~(?<!\D)(\D)~ with lookbehind if you have negative integers
$splits = preg_split('~(\D)~', $equation, -1, PREG_SPLIT_DELIM_CAPTURE);
$bits = [];
array_walk($splits, function($v, $k) use (&$bits) {
$type = $k % 2 == 0 ? 'numbers' : 'operators';
$bits[$type][] = $v;
});
这会导致:
array(2) {
["numbers"] · array(5) {
[0] · string(3) "155"
[1] · string(2) "44"
[2] · string(1) "3"
[3] · string(1) "2"
[4] · string(2) "12"
}
["operators"] · array(4) {
[0] · string(1) "+"
[1] · string(1) "x"
[2] · string(1) "/"
[3] · string(1) "-"
}
}
请注意,如果您有- 有符号整数,则将数字与运算符分开的基本正则表达式将失败。您可以添加一个否定的look-behind,排除运算符前面的减号;然后你的正则表达式看起来像~(?<!\D)(\D)~。
运算符周围可能还有空格。在这种情况下,请在运算符捕获/拆分匹配器正则表达式之外添加可选空格:~\s*(\D)\s*~,以便在捕获运算符本身时在拆分中丢弃空格。
注意您不能将- 有符号数字的负向回溯与 可选 空格结合使用,因为负向回溯需要是固定长度的。您要么有空格(?<!\D\s),要么没有(?<!\D)。这将起作用:~\s*(?<!\D\s)(\D)\s*~ for 155 + 44 x 3 / 2 * -12;而这个~\s*(?<!\D)(\D)\s*~ 用于拆分155+44x3/2*-12。
此外,如果您的方程式使用双字符运算符,例如 PHP 的 ** 用于幂,您将需要修改正则表达式以匹配。如果您有( 括号) 和其他符号,那么它又是另一匹马了。不过,这种方法应该适用于基础知识。