5+6-5*3/2+4
我需要将字符串拆分为两个数组:第一个数组包含整数,第二个数组包含字符串中的运算符。
我使用了preg_split()函数,如下所示:
preg_split("/[^0-9]+/", $str)
我已经成功完成了任务,但我被告知要使用 explode()
和 implode()
函数。我尝试使用它们,但现在我完全不知道如何使用它们来获取所需的数组。
5+6-5*3/2+4
preg_split("/[^0-9]+/", $str)
我已经成功完成了任务,但我被告知要使用 explode()
和 implode()
函数。我尝试使用它们,但现在我完全不知道如何使用它们来获取所需的数组。
在这里,preg_match
可以帮助你解决问题。你也可以使用preg_split
完成此操作。如果你有像这样的字符串5+6-(5*3)/2+4
,那么preg_match
是更好的解决方案,因为preg_split
的结果也会给出(
和)
。在这里,我们使用array_map
进行迭代并防止0
被删除,因为它们可能会被array_filter
移除。
解决方案1:使用preg_match
正则表达式:(\d+)|([+-\/\*])
,这将匹配一个或多个数字或任何算术符号。
<?php
ini_set('display_errors', 1);
$str = "5+6-5*3/2+4+0";
preg_match_all("/(\d+)|([+-\/\*])/", $str,$matches);
$digits=array();
array_map(function($value) use(&$digits){
if($value!=="" && $value!==null && $value!==false)
{
$digits[]=$value;
}
}, $matches[1]);
$symbols=array();
array_map(function($value) use(&$symbols){
if($value!=="" && $value!==null && $value!==false)
{
$symbols[]=$value;
}
}, $matches[2]);
print_r($digits);
print_r($symbols);
解决方案2:使用 preg_split 函数
这里我们使用 preg_split 函数将字符串按照数字 (\d+)
和符号 [+-\/\*]
进行分割。
<?php
ini_set('display_errors', 1);
$str = "5+6-5*3/2+4+0";
$symbols=preg_split("/(\d+)/", $str);
$digits=preg_split("/([+-\/\*])/", $str);
$symbols= array_filter($symbols);
print_r($digits);
print_r($symbols);
$str = "5+6-5*3/2+4";
preg_match_all('!\d+!', $str, $matches);
preg_match_all('/[^0-9]+/', $str, $matches2);
print_r($matches[0]); //integers
echo '<br/>';
print_r($matches2[0]); //operators
function multiexplode ($delimiters,$string) {
$ready = str_replace($delimiters, $delimiters[0], $string);
$launch = explode($delimiters[0], $ready);
return $launch;
}
$resultArray = multiexplode(array('+','-','/','*'), $str);
print_r($resultArray);
echo '<br/>';
$resultArray1 = array_filter(multiexplode(range(0,9), $str));
print_r($resultArray1);
使用preg_split()
对字符串进行两次正则表达式扫描:(演示)
$digits = preg_split("/\D+/", $str, 0, PREG_SPLIT_NO_EMPTY);
$symbols = preg_split("/\d+/", $str, 0, PREG_SPLIT_NO_EMPTY);
使用preg_split()
对字符串进行一次正则表达式扫描:(演示)
foreach (preg_split("/(\d+)/", $str, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE) as $string) {
if (ctype_digit($string)) {
$digits[] = $string;
} else {
$symbols[] = $string;
}
}
使用preg_match_all()
函数对字符串进行一次正则表达式扫描:(演示)
preg_match_all("/(\d+)|(\D+)/", $str, $matches, PREG_SET_ORDER);
foreach ($matches as $match) {
if ($match[1] !== '') {
$digits[] = $match[1];
} else {
$symbols[] = $match[2];
}
}
解释
使用基于正则表达式的解决方案是从输入字符串中提取所需子字符串的唯一明智有效/直接方式。
我们只能假设您的输入字符串仅由数字和符号组成(没有其他字符)。如果有其他字符,则需要调整模式。
在捕获数字时,有四种基本模式可供选择:\d+
、[^\D]
、[0-9]+
、[^-+*/]+
。所有四种模式需要相等数量的“步骤”,因此决定因素是模式简洁性,\d+
获胜。
在捕获符号时,有四种基本模式:\D
、[^\d]
、[^0-9]
、[-+/*]
。所有四种模式需要相等数量的“步骤”,因此决定因素再次是模式简洁性,\D
获胜。
为了进行最佳测试,我将使用 $str = "50+16-0*387/2+49";
作为我的输入,因为它包括一个零和多位整数。
为了让可能会被投票数所影响的研究人员受益,对Sahil的答案进行批判:
[+-\/\*]
是错误的字符类构造方式。该模式匹配以下6个列出的字符之一(但是此任务仅需要4个符号):
+
、,
、-
、.
、/
)换句话说,字符类中的连字符不是按字面意义处理的,而是创建了可接受字符的范围。
使用 array_map()
但忽略其返回值表示函数使用不当。更明智的做法是使用 array_walk()
,但必要的语法更冗长且难以阅读。也可以使用 array_filter()
或 array_reduce()
将过滤后的数组返回到其适当的结果变量,但这意味着对相同数据执行两次循环。使用 foreach()
(作为单次遍历)将是填充两个结果数组的最简洁方法。
preg_split()
调用容易生成空元素,因为没有使用 PREG_SPLIT_NO_EMPTY
标志。
试试这个,我会发布另一种方法。
<?php
error_reporting(0);
$str = "5+6-5*3/2+4";
$array_opartor=preg_split("/[0-9]/", $str);
$array_integer=preg_split("/[^0-9]+/", $str);
$two_array=array_merge($array_opartor,$array_integer);
$all_operator=array();
$all_numeric=array();
foreach($two_array as $array_results)
{
if(is_numeric($array_results))
{
array_push($all_numeric,$array_results);
}
else if($array_results!="")
{
array_push($all_operator,$array_results);
}
}
print_r($all_operator); // View All operator in array
echo "<br/>";
print_r($all_numeric); // View All Numeric value in Array
?>
第二种解决方案
<?php
error_reporting(0);
$str = "5+6-5*3/2+4";
$array_opartor=preg_split("/[0-9]/", $str);
$array_integer=preg_split("/[^0-9]+/", $str);
$all_operator=array_filter($array_opartor);//use thi fo remove all null value in array
print_r($all_operator); // View All operator in array
echo "<br/>";
print_r($array_integer); // View All Numeric value in Array
?>
我喜欢@Sahil Gulati实现的方式,但它不能满足您使用explode-implode的要求。
这是我的代码:
function solution5($S){
$return['digits'] = multipleExplode(array('+','-','/','*'), $S);
$return['symbols']= array_filter(multipleExplode(range(0,9), $S));
return $return;
}
function multipleExplode($del,$str) {
$passStr = str_replace($del, $del[0], $str);
$returnArr = explode($del[0], $passStr);
return $returnArr;
}
var_dump(solution5("5+6-5*3/2+4"));