使用 PHP 将字符串拆分为数字和字符数组的正则表达式
Regex to split string into array of numbers and characters using PHP
我有一个类似于以下模式的算术字符串。
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
输出=> [
0 => '1'
1 => '+'
2 => '2'
3 => '+'
4 => '3'
]
b。 2/1*100
输出=> [
0 => '2'
1 => '/'
2 => '1'
3 => '*'
4 => '100'
]`
c。 1+2+3/3*100
输出=>[
0 => '1'
1 => '+'
2 => '2'
3 => '+'
4 => '3'
5 => '/'
6 => '3'
7 => '*'
8 => '100'
]`
d。 (1*2)/(3*4)*100
输出=>[
0 => '('
1 => '1'
2 => '*'
3 => '2'
4 => ')'
5 => '/'
6 => '('
7 => '3'
8 => '*'
9 => '4'
10 => ')'
11 => '*'
12 => '100'
]
非常感谢您。
使用这个正则表达式:
(?<=[()\/*+-])(?=[0-9()])|(?<=[0-9()])(?=[()\/*+-])
它将匹配数字或括号与运算符或括号之间的每个位置。
(?<=[()\/*+-])(?=[0-9()])
匹配左边有括号或操作符,右边有数字或括号的位置
(?<=[0-9()])(?=[()\/*+-])
同上,左右颠倒
演示 here
正如我所说,如果你能提供一些你自己完成的工作来解决这个问题,我会帮助你。
但是,如果在用算术表达式制作一维数组时,您的 objective 是解析和计算该数组,那么您应该构建一棵树,并通过将运算符作为节点来对其进行分层,分支是操作数:
'(1*2)/(3*4)*100'
Array
(
[operand] => '*',
[left] => Array
(
[operand] => '/',
[left] => Array
(
[operand] => '*',
[left] => 1,
[right] => 2
),
[right] => Array
(
[operand] => '*',
[left] => 3,
[right] => 4
)
),
[right] => 100
)
由于您声明表达式是 "clean",没有空格等,您可以拆分
\b|(?<=\W)(?=\W)
它在非单词字符之间的所有单词边界 和 边界上拆分(使用匹配两个非单词字符之间的位置的正环视)。
不需要为此使用正则表达式。您只需遍历字符串并根据需要构建数组。
编辑,刚刚意识到使用 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);
您也可以使用这个匹配的正则表达式:[()+\-*\/]|\d+
我正在为 php 计算器演示做类似的事情。 A related post.
考虑 preg_split()
的这种模式:
~-?\d+|[()*/+-]~
(Pattern Demo)
这有一个额外的好处,即允许负数而不会使运算符混淆它们。第一个“替代”匹配正整数或负整数,而第二个“替代”(在 |
之后)匹配括号和运算符——一次一个。
在 php 实现中,我将整个模式放在捕获组中并保留分隔符。这样就不会留下任何子字符串。 ~
用作模式分隔符,因此模式中的斜线不需要转义。
代码:(Demo)
$expression = '(1*2)/(3*4)*100+-10';
var_export(
preg_split(
'~(-?\d+|[()*/+-])~',
$expression,
0,
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',
)
我有一个类似于以下模式的算术字符串。
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
输出=> [
0 => '1'
1 => '+'
2 => '2'
3 => '+'
4 => '3'
]
b。 2/1*100
输出=> [
0 => '2'
1 => '/'
2 => '1'
3 => '*'
4 => '100'
]`
c。 1+2+3/3*100
输出=>[
0 => '1'
1 => '+'
2 => '2'
3 => '+'
4 => '3'
5 => '/'
6 => '3'
7 => '*'
8 => '100'
]`
d。 (1*2)/(3*4)*100
输出=>[
0 => '('
1 => '1'
2 => '*'
3 => '2'
4 => ')'
5 => '/'
6 => '('
7 => '3'
8 => '*'
9 => '4'
10 => ')'
11 => '*'
12 => '100'
]
非常感谢您。
使用这个正则表达式:
(?<=[()\/*+-])(?=[0-9()])|(?<=[0-9()])(?=[()\/*+-])
它将匹配数字或括号与运算符或括号之间的每个位置。
(?<=[()\/*+-])(?=[0-9()])
匹配左边有括号或操作符,右边有数字或括号的位置
(?<=[0-9()])(?=[()\/*+-])
同上,左右颠倒
演示 here
正如我所说,如果你能提供一些你自己完成的工作来解决这个问题,我会帮助你。
但是,如果在用算术表达式制作一维数组时,您的 objective 是解析和计算该数组,那么您应该构建一棵树,并通过将运算符作为节点来对其进行分层,分支是操作数:
'(1*2)/(3*4)*100'
Array
(
[operand] => '*',
[left] => Array
(
[operand] => '/',
[left] => Array
(
[operand] => '*',
[left] => 1,
[right] => 2
),
[right] => Array
(
[operand] => '*',
[left] => 3,
[right] => 4
)
),
[right] => 100
)
由于您声明表达式是 "clean",没有空格等,您可以拆分
\b|(?<=\W)(?=\W)
它在非单词字符之间的所有单词边界 和 边界上拆分(使用匹配两个非单词字符之间的位置的正环视)。
不需要为此使用正则表达式。您只需遍历字符串并根据需要构建数组。
编辑,刚刚意识到使用 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);
您也可以使用这个匹配的正则表达式:[()+\-*\/]|\d+
我正在为 php 计算器演示做类似的事情。 A related post.
考虑 preg_split()
的这种模式:
~-?\d+|[()*/+-]~
(Pattern Demo)
这有一个额外的好处,即允许负数而不会使运算符混淆它们。第一个“替代”匹配正整数或负整数,而第二个“替代”(在 |
之后)匹配括号和运算符——一次一个。
在 php 实现中,我将整个模式放在捕获组中并保留分隔符。这样就不会留下任何子字符串。 ~
用作模式分隔符,因此模式中的斜线不需要转义。
代码:(Demo)
$expression = '(1*2)/(3*4)*100+-10';
var_export(
preg_split(
'~(-?\d+|[()*/+-])~',
$expression,
0,
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',
)