我正在创建一个吉他标签到rtttl (铃声文本传输语言)转换器在PHP中。为了准备用于rtttl转换的吉他标签,我首先剥离所有注释(注释由#-标记,并以-#结尾),然后我有几行代码来设置节拍,注意调谐,并定义多个乐器(节拍120\n定义吉他1 \n定义低音1等),从选项卡中剥离并留出供以后使用。
现在,除了吉他标签,我基本上什么都没有了。每个选项卡都以其仪器名称作为前缀,并与前面提到的仪器名称一起使用。
有时我们有两个单独的乐器的标签,这是因为他们是一起演奏的,即吉他和低音吉他一起演奏。
示例1,标准吉他选项卡:
|Guitar 1
e|--------------3-------------------3------------|
B|------------3---3---------------3---3----------|
G|----------0-------0-----------0-------0--------|
D|--------0-----------0-------0-----------0------|
A|------2---------------2---2---------------2----|
E|----3-------------------3-------------------3--|示例2,连接选项卡:
|Guitar 1
e|--------------3-------------------3------------|
B|------------3---3---------------3---3----------|
G|----------0-------0-----------0-------0--------|
D|--------0-----------0-------0-----------0------|
A|------2---------------2---2---------------2----|
E|----3-------------------3-------------------3--|
|
|
|Bass 1
G|----------0-------0-----------0-------0--------|
D|--------2-----------2-------2-----------2------|
A|------3---------------3---3---------------3----|
E|----3-------------------3-------------------3--|我已经考虑过其他识别选项卡的方法,但没有可靠的结果。我希望有人谁做正则表达式可以帮助我找到一种方法来确定一个单一的吉他标签,如果可能的话,也能够匹配多个乐器链接在一起的标签。
一旦制表符在数组中,我将一次一行地遍历它们,并将它们转换为rtttl行(在每个新行“\n”处展开)。
我不想通过拆分"\n\n“或类似的东西来分隔文档中的吉他标签,因为它不标识吉他标签,而是标识标签之间的空间-而不是标签本身。
我已经搞了大约一个星期了,这是我唯一的主要障碍。其他的一切都相当简单。
到目前为止,我已经尝试了regex模式的许多变体。以下是最新的测试样本之一:
<?php
$t = "
|Guitar 1
e|--------------3-------------------3------------|
B|------------3---3---------------3---3----------|
G|----------0-------0-----------0-------0--------|
D|--------0-----------0-------0-----------0------|
A|------2---------------2---2---------------2----|
E|----3-------------------3-------------------3--|
|Guitar 1
e|--------------3-------------------3------------|
B|------------3---3---------------3---3----------|
G|----------0-------0-----------0-------0--------|
D|--------0-----------0-------0-----------0------|
A|------2---------------2---2---------------2----|
E|----3-------------------3-------------------3--|
|
|
|Bass 1
G|----------0-------0-----------0-------0--------|
D|--------2-----------2-------2-----------2------|
A|------3---------------3---3---------------3----|
E|----3-------------------3-------------------3--|
";
preg_match_all("/^.*?(\\|).*?(\\|)/is",$t,$p);
print_r($p);
?>还值得注意的是,在短划线和#所在的制表符内部,您也可以使用字母、数字和标点符号的任何变体。每行的开头使用以下不区分大小写的字符之一来标记每个字符串的调整: a、a#、b、c、c#、d、d#、e、f、f#、g或g。
提前感谢你对这个最难的问题的帮助。
发布于 2010-06-04 03:07:40
我很喜欢这个问题:-P。我找到了解决这个问题的乐趣。
下面是我得到的信息:
<?php
$t = <<<EOD
|Guitar 1
e|--------------3-------------------3------------|
B|------------3---3---------------3---3----------|
G|----------0-------0-----------0-------0--------|
D|--------0-----------0-------0-----------0------|
A|------2---------------2---2---------------2----|
E|----3-------------------3-------------------3--|
|Guitar 1
e|--------------3-------------------3------------|
B|------------3---3---------------3---3----------|
G|----------0-------0-----------0-------0--------|
D|--------0-----------0-------0-----------0------|
A|------2---------------2---2---------------2----|
E|----3-------------------3-------------------3--|
|
|
|Bass 1
G|----------0-------0-----------0-------0--------|
D|--------2-----------2-------2-----------2------|
A|------3---------------3---3---------------3----|
E|----3-------------------3-------------------3--|
EOD;
GetTabs($t);
function GetTabs($tabString) {
$tabs = array();
$tabcount = 0;
$instrumentcount = 0;
$tabline = 0;
$tabStringArray = explode("\n", $tabString);
foreach ($tabStringArray as $tabStringRow) {
if (preg_match ('/^(?<snaretuningprefix>[bgdaeBGDAE#])+\|(?<tabline>[0-9-]+)\|/', $tabStringRow)) {
//Matches a tab line
//The tabline group can be expanded with characters for hammer on's, pull off's and whatnot
$tabs[$tabcount][$instrumentcount-1][$tabline] = $tabStringRow;
$tabline++;
continue;
}
if (preg_match ('/^\s\|\s+/', $tabStringRow, $matches)) {
//Matches ' |'
//Continuation of tab do nothing
continue;
}
if (preg_match ('/^\s\|(?<instrument>[A-z0-9\s]+)/', $tabStringRow, $matches)) {
//Matches an instrument line ' |Guitar 1'
$tabs[$tabcount][$instrumentcount]['instrumentname'] = $matches['instrument'];
$instrumentcount++;
$tabline = 0;
continue;
}
if (preg_match ('/^\s+/', $tabStringRow)) {
//Matches empty line
//new tab
$tabcount++;
$instrumentcount = 0;
continue;
}
}
print_r($tabs);
}
?>这个函数有一些注释,我想它读起来并不难。
这将输出以下内容:
Array
(
[0] => Array
(
[0] => Array
(
[instrumentname] => Guitar 1
[0] => e|--------------3-------------------3------------|
[1] => B|------------3---3---------------3---3----------|
[2] => G|----------0-------0-----------0-------0--------|
[3] => D|--------0-----------0-------0-----------0------|
[4] => A|------2---------------2---2---------------2----|
[5] => E|----3-------------------3-------------------3--|
)
)
[1] => Array
(
[0] => Array
(
[instrumentname] => Guitar 1
[0] => e|--------------3-------------------3------------|
[1] => B|------------3---3---------------3---3----------|
[2] => G|----------0-------0-----------0-------0--------|
[3] => D|--------0-----------0-------0-----------0------|
[4] => A|------2---------------2---2---------------2----|
[5] => E|----3-------------------3-------------------3--|
)
[1] => Array
(
[instrumentname] => Bass 1
[0] => G|----------0-------0-----------0-------0--------|
[1] => D|--------2-----------2-------2-----------2------|
[2] => A|------3---------------3---3---------------3----|
[3] => E|----3-------------------3-------------------3--|
)
)
)发布于 2010-06-04 02:57:37
我不完全确定你到底是什么意思,但是如果你想用工具来分隔标签页,试试这个:
^[^|\r\n]+\|([^|\r\n]+)$\r?\n # match the line that contains the instrument name
# and capture this in backreference 1
( # capture the block of lines that follows
(?: # repeat this for each line
^[^|\r\n]+ # everything up to the first |
\| # |
[^|\r\n]+ # everything up to the next |
\| # |
\r?\n # newline
)+ # at least once
) # end capture在PHP中:
preg_match_all('/^[^|\r\n]+\|([^|\r\n]+)$\r?\n((?:^[^|\r\n]+\|[^|\r\n]+\|\r?\n)+)/im', $subject, $result, PREG_PATTERN_ORDER);
for ($i = 0; $i < count($result[0]); $i++) {
# Matched text = $result[0][$i];
}每个匹配项的形式为
|Bass 1
G|----------0-------0-----------0-------0--------|
D|--------2-----------2-------2-----------2------|
A|------3---------------3---3---------------3----|
E|----3-------------------3-------------------3--|而这些块之间的其他所有内容都将被忽略。
发布于 2010-06-04 02:48:29
正则表达式中的^将阻止/s开关执行您想要的操作。
此外,preg_match_all将返回大量重复的"matches“,因为您使用的是()分组。如果您计划对具有多个选项卡的文件使用preg_match_all(),则可能很难使用这些重复项来隔离真实的匹配项。
https://stackoverflow.com/questions/2968539
复制相似问题