如何使用explode-implode函数将字符串分割为两个数组?

5
假设我有以下字符串:
5+6-5*3/2+4

我需要将字符串拆分为两个数组:第一个数组包含整数,第二个数组包含字符串中的运算符。
我使用了preg_split()函数,如下所示:
preg_split("/[^0-9]+/", $str)

我已经成功完成了任务,但我被告知要使用 explode()implode() 函数。我尝试使用它们,但现在我完全不知道如何使用它们来获取所需的数组。


String类中没有你想要的方法,你需要编写自己的函数。例如,你需要检查字符串的字符并判断其是否为整数或特殊字符。 - Bhavishya Prajapati
5个回答

9

在这里,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);

1
请为我尝试以下工作。
第一种方法
$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);

1

使用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的答案进行批判:

  1. [+-\/\*] 是错误的字符类构造方式。该模式匹配以下6个列出的字符之一(但是此任务仅需要4个符号):

    • 从连字符到正斜杠之间的任何字符(+,-./
    • 一个字面上的星号(无需转义)

    换句话说,字符类中的连字符不是按字面意义处理的,而是创建了可接受字符的范围。

  2. 使用 array_map() 但忽略其返回值表示函数使用不当。更明智的做法是使用 array_walk(),但必要的语法更冗长且难以阅读。也可以使用 array_filter()array_reduce() 将过滤后的数组返回到其适当的结果变量,但这意味着对相同数据执行两次循环。使用 foreach()(作为单次遍历)将是填充两个结果数组的最简洁方法。

  3. preg_split() 调用容易生成空元素,因为没有使用 PREG_SPLIT_NO_EMPTY 标志。


0

试试这个,我会发布另一种方法。

<?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
    ?>

因为你的代码没有解释;你的代码效率低下;你的输出结果不符合OP的要求,最后你的代码因为未定义变量而产生了2个NOTICES。这不是恶意评论,这是反馈。如果我是恶意评论者,我就不会留言了。请考虑编辑你的问题,创建一个新的、独特的、高效的、有价值的、完整的答案;或者如果你不能或不想这样做,请删除你的答案以减少页面膨胀。 - mickmackusa
我恐怕无法取消我的踩投票,因为你的编辑是 Sahil Gulati 早先发布的答案的重复。最好的做法可能是删除你的回答,因为我认为所有最好/最有效的答案都已经提供了。(如果你能创建一种新的、独特的、高效的、有价值的方法,欢迎你证明我是错的。) - mickmackusa

0

我喜欢@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"));

也许这对你解决你的问题有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接