【问题标题】:How to split a string into two arrays using explode-implode functions?如何使用explode-implode函数将字符串拆分为两个数组?
【发布时间】:2017-09-22 07:33:10
【问题描述】:

假设我有以下字符串:

5+6-5*3/2+4

我需要将字符串分成两个数组:第一个数组包含整数,第二个数组包含字符串中的运算符。

我用过preg_split()函数,像这样

preg_split("/[^0-9]+/", $str)

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

【问题讨论】:

  • String 类中没有您想要的方法,您必须编写我们自己的函数。就像您必须检查字符串的租船者并检查是整数还是空格字符。

标签: php arrays regex input split


【解决方案1】:

这里preg_match也可以帮到你。您也可以使用preg_split 来完成。 preg_match 是一个更好的解决方案,如果你有这样的字符串5+6-(5*3)/2+4 然后preg_split 结果也给你()。在这里,我们使用array_map 来迭代和防止0 可能会被array_filter 删除。

Try this code snippet here

解决方案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);

Try this code snippet here

解决方案 2: using 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);

【讨论】:

    【解决方案2】:

    帮我试试这个工作

    第一种方法

    $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);
    

    【讨论】:

      【解决方案3】:

      对带有preg_split()的字符串进行两次正则表达式扫描: (Demo)

      $digits = preg_split("/\D+/", $str, 0, PREG_SPLIT_NO_EMPTY);
      $symbols = preg_split("/\d+/", $str, 0, PREG_SPLIT_NO_EMPTY);
      

      对带有preg_split()的字符串进行一次正则表达式扫描: (Demo)

      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()的字符串进行一次正则表达式扫描: (Demo)

      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. [+-\/\*] 正在教授不良品格课程建设。此模式is saying 匹配以下列出的 6 个字符中的任何一个(但此任务只需要 4 个符号):

        • 从连字符到正斜杠的任何字符(+,-./
        • 字面星号(不需要转义)

        换句话说,字符类中的连字符没有按字面意思处理,它创建了一系列可接受的字符。

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

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

      【讨论】:

        【解决方案4】:

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

        也许这可以帮助您解决问题。

        【讨论】:

          【解决方案5】:

          试试这个 我正在发布另一种方法

          <?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 个通知。这不是拖钓,这是反馈​​。如果我是巨魔,我不会发表评论。请考虑编辑您的问题以创建一个新的、独特的、高效的、有价值的、完整的答案;或者如果您不能或不想这样做,请删除您的答案以减少页面膨胀。
          • 恐怕我无法删除我的反对意见,因为您的编辑与 Sahil Gulati 先前发布的答案重复。最好简单地删除您的答案,因为我相信已经提供了所有最好/最有效的答案。 (如果你能创造出一种新的、独特的、有效的、有价值的方法,欢迎你证明我错了。)
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-11-15
          • 1970-01-01
          • 2017-10-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多