使用preg_split分割和弦和单词

时间:2015-12-16 10:50:20

标签: php parsing preg-split

我正在制作处理歌曲标签的一小段代码,但我遇到了问题。

我需要解析每个歌曲标签行并将其拆分为一方面获取和弦的块,另一方面

每个块都会像:

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

他们应该保持"分组"。我的意思是,只有当函数达到" limit"和弦之间的关系。

我想我应该使用 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
    ),
);

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

谢谢!

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

我会使用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"];
}

Boudaries不会在代码中进行测试,也不会在剩余的空格中进行测试,但它是一个可以工作的基础。