正则表达式使用PHP将字符串拆分为数字和字符数组

时间:2017-08-10 07:45:44

标签: php regex preg-match preg-split

我有一个算术字符串,类似于以下模式。

a. 1+2+3
b. 2/1*100
c. 1+2+3/3*100
d. (1*2)/(3*4)*100

需要注意的是
1.字符串永远不会包含空格 2.字符串将始终是数字,算术符号(+, - ,*,/)和字符'('和')'

的组合

我正在寻找PHP中的正则表达式,根据其类型拆分字符,并形成一个单独的字符串字符数组,如下所示。
(注意:我不能使用str_split,因为我希望不要拆分大于10的数字。)

一个。 1+2+3
output => [
        0 => '1'
        1 => '+'
        2 => '2'
        3 => '+'
        4 => '3'
]

2/1*100
output => [
        0 => '2'
        1 => '/'
        2 => '1'
        3 => '*'
        4 => '100'
]`

℃。 1+2+3/3*100

output => [
        0 => '1'
        1 => '+'
        2 => '2'
        3 => '+'
        4 => '3'
        5 => '/'
        6 => '3'
        7 => '*'
        8 => '100'
]`

d。 (1*2)/(3*4)*100

output => [
        0 => '('
        1 => '1'
        2 => '*'
        3 => '2'
        4 => ')'
        5 => '/'
        6 => '('
        7 => '3'
        8 => '*'
        9 => '4'
        10 => ')'
        11 => '*'
        12 => '100'
]

非常感谢你。

5 个答案:

答案 0 :(得分:1)

使用此正则表达式:
(?<=[()\/*+-])(?=[0-9()])|(?<=[0-9()])(?=[()\/*+-])

它将匹配数字或括号与运算符或括号之间的每个位置 (?<=[()\/*+-])(?=[0-9()])匹配左侧的括号或运算符以及右侧的数字或括号的位置 (?<=[0-9()])(?=[()\/*+-])是相同的,但左右颠倒了。

演示here

答案 1 :(得分:1)

由于您声明表达式为&#34; clean&#34;,没有空格等,您可以拆分

\b|(?<=\W)(?=\W)

它分割所有单词边界非单词字符之间的边界(使用与两个非单词字符之间的位置匹配的正面外观)。

See an illustration here at regex101

答案 2 :(得分:0)

没有必要为此使用正则表达式。您只需循环遍历字符串并根据需要构建数组。

编辑,刚刚意识到使用while循环而不是两个for循环和if()可以更快地完成它。

$str ="(10*2)/(3*40)*100";
$str = str_split($str); // make str an array

$arr = array();
$j=0; // counter for new array
for($i=0;$i<count($str);$i++){ 
    if(is_numeric($str[$i])){ // if the item is a number
        $arr[$j] = $str[$i]; // add it to new array 
        $k = $i+1;
        while(is_numeric($str[$k])){ // while it's still a number append to new array item.
            $arr[$j] .= $str[$k]; 
            $k++; // add one to counter.
            if($k == count($str)) break; // if counter is out of bounds, break loop.
        }
        $j++; // we are done with this item, add one to counter.
        $i=$k-1; // set new value to $i
    }else{
        // not number, add it to the new array and add one to array counter.
        $arr[$j] = $str[$i]; 
        $j++;
    }
}

var_dump($arr);

https://3v4l.org/p9jZp

答案 3 :(得分:0)

您也可以使用此匹配的正则表达式:[()+\-*\/]|\d+

Demo

答案 4 :(得分:0)

我正在为php计算器演示做类似的事情。 A related post

考虑preg_split()

的这种模式

~-?\d+|[()*/+-]~Pattern Demo

这具有允许负数而不会使运营商混淆的额外好处。第一个“替代”匹配正整数或负整数,而第二个“替代”(在|之后)匹配括号和运算符 - 一次一个。

在php实现中,我将整个模式放在捕获组中并保留分隔符。这样就不会留下任何子串。 ~用作模式分隔符,因此模式中的斜杠不需要转义。

代码:(Demo

$expression='(1*2)/(3*4)*100+-10';
var_export(preg_split('~(-?\d+|[()*/+-])~',$expression,NULL,PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE));

输出:

array (
  0 => '(',
  1 => '1',
  2 => '*',
  3 => '2',
  4 => ')',
  5 => '/',
  6 => '(',
  7 => '3',
  8 => '*',
  9 => '4',
  10 => ')',
  11 => '*',
  12 => '100',
  13 => '+',
  14 => '-10',
)