使用preg_split分割和弦和单词

gor*_*die 6 php parsing preg-split

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

我需要解析每个歌曲标签行并将其拆分以一方面获得大量的和弦,另一方面提供单词.

每个块都会像:

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

他们应该保持"分组".我的意思是,只有当函数达到和弦和单词之间的"限制"时它才会分裂.

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

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

这些例子向您展示了我想要的内容:

在不含和弦的行上:

$input = '{intro}';

$results = array(
    array(
        0 => null,
        1 => '{intro}
    )
);
Run Code Online (Sandbox Code Playgroud)

在仅包含和弦的行上:

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

$results = array(
    array(
        0 => '[C#] [Fm] [C#] [Fm] [C#] [Fm]',
        1 => null
    )
);
Run Code Online (Sandbox Code Playgroud)

在包含两者的一行上:

$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
    ),
);
Run Code Online (Sandbox Code Playgroud)

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

谢谢 !

Cas*_*yte 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);
}
Run Code Online (Sandbox Code Playgroud)

演示

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

注:欢迎补充:

if (empty($i[1])) $i[1] = null;    
if (empty($i[2])) $i[2] = null;
Run Code Online (Sandbox Code Playgroud)

如果您想获取空项目而不是空项目,请在地图函数中使用。

注2:如果逐行工作,可以\n从图案中删除 。