使用preg_match_all创建和弦图表

时间:2011-02-15 22:38:53

标签: php

我想在有人输入歌词时创建PDF和弦图表。输入歌词的格式如下:

[B]Some lyrics blah blah [D]more lyrics blah
Lyrics without any chord charts blah blah
Some lyrics [C]blah blah more [E]lyrics blah

然后我想提取每个和弦变化,以便我可以导出并以PDF格式显示它:

B                     D
Some lyrics blah blah more lyrics blah
Lyrics without any chord charts blah blah
            C              E
Some lyrics blah blah more lyrics blah

我还有其他一切排序。目前我只需要弄清楚如何将每个和弦与和弦本身之间的所有文本外推...

这是我目前的代码:

$lyrics = '[B]Some lyrics blah blah [D]more lyrics blah
Lyrics without any chord charts blah blah
Some lyrics [C]blah blah more [E]lyrics blah';

$lyrics_html = '';
$x = 0;
$lyrics_lines = explode("\n", $lyrics);

// We've put each line into an array and now we will process each individually
foreach($lyrics_lines AS $lyrics_line) {

    $x++;
    if ($x > 1)
        $lyrics_html .= '<br />';

    // Check and see if an chords exist in this line
    preg_match_all('/\[(\w{1,3})\]/i',
    $lyrics_line,
    $out);

    if (!empty($out[0])) { // Found some chords, format it

        print_r($out);

    } else { // No chords found so just display the lyrics

        $lyrics_html .= $lyrics_line;

    }

}

echo $lyrics_html;

我的以下代码选择了和弦而不用担心

preg_match_all('/\[(\w{1,3})\]/i',
    $lyrics_line,
    $out);

但是当我尝试在和弦之前和之后选择文字时,我似乎无法弄明白......我尝试了以下内容:

preg_match_all('/(\w+)\[(\w{1,3})\](\w+)/i',
    $lyrics_line,
    $out);

任何想法我需要什么代码,以便我可以选择和弦和歌词,以便我可以格式化它们?

这样的结果会是这样的:

Array
(
    [0] => Array
        (
        [0] => [B]
        [1] => [D]
        )

    [1] => Array
        (
        [0] => Some lyrics blah bla
        [1] => more lyrics blah
        )

)

2 个答案:

答案 0 :(得分:4)

有趣的问题......这是一个可能的解决方案。我使用了你的正则表达式,但也使用它来查看填充和弦需要多少空格。

<?php
define('REGEX_CHORD', '[A-G].*?');

$input = '[B]Some lyrics blah blah [D]more lyrics blah
Lyrics without any chord charts blah blah
Some lyrics [C]blah blah more [E]lyrics blah';

$lines = explode("\n", $input);
echo '<pre>';
foreach($lines as $line) {
    $chordline = '';
    $tmpline = $line;
    while(preg_match('~(.*)\[('.REGEX_CHORD.')\]~', $tmpline, $matches)) {
        // Length before the chord shows how many spaces are required.
        $chordline = str_repeat(' ', strlen($matches[1]))
                .$matches[2]
                .substr($chordline, 
                    strlen($matches[2]) + 3 + strlen($matches[1]));
        $tmpline = $matches[1];
    }
    echo $chordline."\n";
    echo preg_replace('~\[('.REGEX_CHORD.')\]~', '', $line)."\n";
}

答案 1 :(得分:0)

我认为这是你正在寻找的preg_match:

/(\[[A-G].*?\])/

它捕获任何被方括号括起来的和弦和跟随符号。它甚至可以匹配下面的平面,锐利和修改器:

[B]Some lyrics blah blah [D]more lyrics blah
Lyrics without any chord charts blah blah
Some lyrics [C]blah blah more [E]lyrics blah


[Bb]Some lyrics blah blah [Dm7+9]more lyrics blah
Lyrics without any chord charts blah blah
Some lyrics [C]blah blah more [Eb]lyrics blah

请参阅此处的工作示例:http://regexr.com?2t408