【问题标题】:use preg_split to split chords and words使用 preg_split 分割和弦和单词
【发布时间】:2015-12-16 10:50:19
【问题描述】:

我正在编写一段代码来播放处理歌曲标签,但我遇到了一个问题。

我需要解析每个歌曲标签行并将其拆分,一方面得到和弦块,另一方面得到单词

每个块都是这样的:

$line_chunk = array(
    0 => //part of line containing one or several chords
    1 => //part of line containing words
);

他们应该保持“分组”。我的意思是只有当函数达到和弦和单词之间的“限制”时才应该拆分。

我想我应该使用 preg_split 来实现这一点。我做了一些测试,但我只能分割和弦,而不是和弦的“组”:

$line_chunks = preg_split('/(\[[^]]*\])/', $line, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);

这些例子向你展示了我想要得到的东西:

在不包含和弦的行上:

$input = '{intro}';

$results = array(
    array(
        0 => null,
        1 => '{intro}
    )
);

在只包含和弦的行上:

$input = '[C#] [Fm] [C#] [Fm] [C#] [Fm]';

$results = array(
    array(
        0 => '[C#] [Fm] [C#] [Fm] [C#] [Fm]',
        1 => null
    )
);

在包含两者的行上:

$input = '[C#]I’m looking for [Fm]you [G#]';

$results = array(
    array(
        0 => '[C#]',
        1 => 'I’m looking for'
    ),
    array(
        0 => '[Fm]',
        1 => 'you '
    ),
    array(
        0 => '[G#]',
        1 => null
    ),
);

关于如何做到这一点的任何想法?

谢谢!

【问题讨论】:

    标签: php parsing preg-split


    【解决方案1】:

    preg_split 不是要走的路。大多数时候,当您有一个复杂的拆分任务要完成时,尝试匹配您感兴趣的内容比尝试使用不容易定义分隔符进行拆分更容易。

    preg_match_all 方法:

    $pattern = '~ \h*
    (?|        # open a "branch reset group"
        ( \[ [^]]+ ] (?: \h* \[ [^]]+ ] )*+ ) # one or more chords in capture group 1
        \h*
        ( [^[\n]* (?<=\S) )  # eventual lyrics (group 2)
      |                      # OR
        ()                   # no chords (group 1)
        ( [^[\n]* [^\s[] )   # lyrics (group 2)
    )          # close the "branch reset group"
    ~x';
    
    if (preg_match_all($pattern, $input, $matches, PREG_SET_ORDER)) {
        $result = array_map(function($i) { return [$i[1], $i[2]]; }, $matches);
        print_r($result);
    }
    

    demo

    分支重置组为每个分支保留相同的组编号。

    注:欢迎补充:

    if (empty($i[1])) $i[1] = null;    
    if (empty($i[2])) $i[2] = null;
    

    如果要获取空项而不是空项,请在 map 函数中。

    注意2:如果你逐行工作,你可以从模式中删除\n

    【讨论】:

      【解决方案2】:

      我会选择 PHP explode:

      /*
       * Process data
       */
      $input = '[C#]I’m looking for [Fm]you [G#]';
      $parts = explode("[", $input);
      $results = array();
      
      foreach ($parts as $item)
      {
          $pieces = explode("]", $item);
      
          if (count($pieces) < 2)
          {
              $arrayitem = array( "Chord" => $pieces[0],
                                  "Lyric" => "");
          }
          else
          {
              $arrayitem = array( "Chord" => $pieces[0],
                                  "Lyric" => $pieces[1]);
          }
      
          $results[] = $arrayitem;
      }
      
      /*
       * Echo results
       */
      foreach ($results as $str)
      {
          echo "Chord: " . $str["Chord"];
          echo "Lyric: " . $str["Lyric"];
      }
      

      在代码中没有测试边界以及剩余的空格,但它是工作的基础。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-20
        相关资源
        最近更新 更多