【问题标题】:Split/parse a PHP string by separate certain words通过分隔某些单词来拆分/解析 PHP 字符串
【发布时间】:2012-05-13 14:36:36
【问题描述】:

我搜索了 PHP 手册、Stackoverflow 和一些论坛,但我对一些 PHP 逻辑感到困惑。也许我只是累了,但我真的很感谢任何人的帮助或指导。

我有一个 PHP 字符串,比如说:

 $string = 'cats cat1 cat2 cat3 dogs dog1 dog2 monkey creatures monkey_creature1 monkey_creature2 monkey_creature3';

最终,理想情况下,我希望我的最终输出看起来像这样,但现在只需获取数组就可以了:

 <h2>cats</h2>
 <ul>
     <li>cat1</li>
     <li>cat2</li>
     <li>cat3</li>
 </ul>

 <h2>dogs</h2>
 <ul>
     <li>dog1</li>
     <li>dog2</li>
 </ul>

 <h2>monkey creatures</h2>
 <ul>
     <li>monkey_creature1</li>
     <li>monkey_creature2</li>
     <li>monkey_creature3</li>
 </ul>

但有一个问题,有时字符串会略有不同:

 $string = 'cats cat1 cat2 cat3 cat4 cat5 cats6 dogs dogs1 dogs2 monkey creatures monkey_creature1 lemurs lemur1 lemur2 lemur3';

无论如何,这是我在 Stackoverflow 上的第一个问题,在此先感谢大家的帮助!

编辑:我在某些限制下工作,我无法更改字符串之前的任何代码。我知道所有的父母('猫','狗','狐猴','猴子生物(有空间)'

【问题讨论】:

  • 哦。这是一个非常好的问题。我认为它会从explode(" ", $string) 开始,但这只是其中的第一步。做出一个俗气的假设是否安全,比如前 3 个字母对于一个组来说总是唯一的
  • monkey creatures 并没有像它应该的那样真正与它的孩子相关。另外,为什么你的数据源是这样格式化的?
  • @jprofitt 我知道...查看我的编辑。
  • @BenRoux 我想像这样,但我无法弄清楚整个过程中的逻辑。我会提前知道所有的父母(猫、狗、猴子、狐猴等)
  • 示例字符串中是monkey creatures 还是monkey_creatures?这很重要

标签: php string parsing split explode


【解决方案1】:

您可能希望使用preg_match_all 函数并使用正则表达式。这样,您就不必使用任何循环:

$matches = array();
$string = 'cats cat1 cat2 cat3 dogs dog1 dog2 monkey creatures monkey_creature1 monkey_creature2 monkey_creature3'
preg_match_all('/((?:[a-z]+ )*?[a-z]+s) ((?:[a-z_]+[0-9] ?)+)*/i', $string, $matches);

// $matches now contains multidemensional array with 3 elements, indices
// 1 and 2 contain the animal name and list of those animals, respectively
$animals = array_combine($matches[1], $matches[2]);
$animals = array_map(function($value) {
    return explode(' ', trim($value));
}, $animals);
print_r($animals);

输出:

Array
(
    [cats] => Array
        (
            [0] => cat1
            [1] => cat2
            [2] => cat3
        )

    [dogs] => Array
        (
            [0] => dog1
            [1] => dog2
        )

    [monkey creatures] => Array
        (
            [0] => monkey_creature1
            [1] => monkey_creature2
            [2] => monkey_creature3
        )

)

【讨论】:

    【解决方案2】:

    认为我将无法提交最佳答案,因此决定以最少的行数运行。 (开个玩笑,非常脏的代码对不起)

    $string = 'cats cat1 cat2 cat3 cat4 cat5 cats6 dogs dogs1 dogs2 monkey creatures monkey_creature1 lemurs lemur1 lemur2 lemur3';
    $categories = array( 'cats', 'dogs', 'monkey creatures', 'lemurs' );
    
    for( $i=0; $i<count( $categories ); $i++ ) $parts[] = @explode( ' ', strstr( $string, $categories[$i] ) );
    for( $i=0; $i<count( $parts ); $i++ ) $groups[] = ($i<count($parts)-1) ? array_diff( $parts[$i], $parts[$i+1] ) : $parts[$i];
    for( $i=0; $i<count( $groups ); $i++ ) for( $j=0; $j<count( $groups[$i] ); $j++ ) if( ! is_numeric( substr( $groups[$i][$j], -1 ) ) ) unset($groups[$i][$j]);
    
    print_r( $groups );
    

    您可能会注意到我的方法取决于元素应该具有数字后缀这一事实。这实际上是无稽之谈,但作为我们正在处理的输入。

    我的输出是:

    Array
    (
        [0] => Array
            (
                [1] => cat1
                [2] => cat2
                [3] => cat3
                [4] => cat4
                [5] => cat5
                [6] => cats6
            )
    
        [1] => Array
            (
                [1] => dogs1
                [2] => dogs2
            )
    
        [2] => Array
            (
                [2] => monkey_creature1
            )
    
        [3] => Array
            (
                [1] => lemur1
                [2] => lemur2
                [3] => lemur3
            )
    
    )
    

    【讨论】:

      【解决方案3】:

      这是我的 0.50 美元

      <?php
      $parents = array('cats', 'dogs', 'lemurs', 'monkey creatures');
      
      // Convert all spaces to underscores in parents
      $cleaned_parents = array();
      foreach ($parents as $parent)
      {
              $cleaned_parents[] = str_replace(' ', '_', $parent);
      }
      
      $input = 'cats cat1 cat2 cat3 dogs dog1 dog2 monkey creatures monkey_creature1 monkey_creature2 monkey_creature3';
      
      // Change all parents to the "cleaned" versions with underscores
      $input = str_replace($parents, $cleaned_parents, $input);
      
      // Make an array of all tokens in the input string
      $tokens = explode(' ', $input);
      $result = array();
      
      // Loop through all the tokens
      $currentParent = null; // Keep track of current parent
      foreach ($tokens as $token)
      {
          // Is this a parent?
          if (in_array($token, $cleaned_parents))
          {
              // Create the parent in the $result array
              $currentParent = $token;
              $result[$currentParent] = array();
          }
          elseif ($currentParent != null)
          {
              // Add as child to the current parent
              $result[$currentParent][] = $token;
          }
      }
      
      print_r($result);
      

      输出:

      Array
      (
          [cats] => Array
              (
                  [0] => cat1
                  [1] => cat2
                  [2] => cat3
              )
      
          [dogs] => Array
              (
                  [0] => dog1
                  [1] => dog2
              )
      
          [monkey_creatures] => Array
              (
                  [0] => monkey_creature1
                  [1] => monkey_creature2
                  [2] => monkey_creature3
              )
      
      )
      

      【讨论】:

        【解决方案4】:

        您的第二个字符串示例:

        <?php
        
        $parents = array('cats', 'dogs', 'monkey creatures', 'lemurs');
        $result = array();
        
        $dataString = 'cats cat1 cat2 cat3 cat4 cat5 cats6 dogs dogs1 dogs2 monkey creatures monkey_creature1 lemurs lemur1 lemur2 lemur3';
        foreach ($parents as $parent) {
          // Consider group only if it is present in the data string
          if (strpos($dataString, $parent) !== false) {
            $result[$parent] = array();
          }
        }
        $parts = explode(' ', $dataString);
        foreach (array_keys($result) as $group) {
          $normalizedGroup = str_replace(' ', '_', $group);
          foreach ($parts as $part) {
            if (preg_match("/^$normalizedGroup?\d+$/", $part)) {
              $result[$group][] = $part;
            }
          }
        }
        print_r($result);
        

        输出:

        Array
        (
            [cats] => Array
                (
                    [0] => cat1
                    [1] => cat2
                    [2] => cat3
                    [3] => cat4
                    [4] => cat5
                    [5] => cats6
                )
        
            [dogs] => Array
                (
                    [0] => dogs1
                    [1] => dogs2
                )
        
            [monkey creatures] => Array
                (
                    [0] => monkey_creature1
                )
        
            [lemurs] => Array
                (
                    [0] => lemur1
                    [1] => lemur2
                    [2] => lemur3
                )
        
        )
        

        【讨论】:

        • 感谢您花时间写这篇文章
        【解决方案5】:

        我设计了一个无论“关键字”之间是否有空格都可以使用的答案,只要第一个关键字不是复数:)

        下面是代码,请随意查看,你可以用文字做什么真的很漂亮:)

        <?
        $string = 'cats cat1 cat2 cat3 dogs dog1 dog2 monkey creatures monkey_creature1 monkey_creature2 monkey_creature3';
        
        $current_prefix = '';
        $potential_prefix_elements = array();
        
        $word_mapping = array();
        
        foreach(split(" ", $string) as $substring) {
            if(strlen($current_prefix)) {
                // Check to see if the current substring, starts with the prefix
                if(strrpos($substring, $current_prefix) === 0)
                    $word_mapping[$current_prefix . 's'][] = $substring;
                else
                    $current_prefix = '';
            }
        
            if(!strlen($current_prefix)) {
                if(preg_match("/(?P<new_prefix>.+)s$/", $substring, $matches)) {
                    $potential_prefix_elements[] = $matches['new_prefix'];
        
                    // Add an 's' to make the keys plural
                    $current_prefix = join("_", $potential_prefix_elements);
        
                    // Initialize an array for the current word mapping
                    $word_mapping[$current_prefix . 's'] = array();
        
                    // Clear the potential prefix elements
                    $potential_prefix_elements = array();
                } else {
                    $potential_prefix_elements[] = $substring;
                }
            }
        }
        
        print_r($word_mapping);
        

        这是输出,我已将其作为数组提供给您,因此您可以轻松构建 ul / li 层次结构:)

        Array
        (
            [cats] => Array
                (
                    [0] => cat1
                    [1] => cat2
                    [2] => cat3
                )
        
            [dogs] => Array
                (
                    [0] => dog1
                    [1] => dog2
                )
        
            [monkey_creatures] => Array
                (
                    [0] => monkey_creature1
                    [1] => monkey_creature2
                    [2] => monkey_creature3
                )
        
        )
        

        【讨论】:

        • 顺便说一下,此代码也适用于您的狐猴示例,它是完全动态的,并且将基于复数起始关键字构建数组,然后检查该前缀的每个后续单词。一旦一个词打破了与前缀的比较,脚本就开始构建一个新的键
        • 谢谢。超级及时,正是我需要的!
        猜你喜欢
        • 2011-11-29
        • 1970-01-01
        • 2011-09-11
        • 2019-04-04
        • 1970-01-01
        • 2016-03-03
        • 2014-03-02
        • 1970-01-01
        • 2016-12-27
        相关资源
        最近更新 更多