Хочу сделать, чтобы программа определяла строки в которых содержатся аккорды, для последующей их подсветки. К примеру строка "Am Dm B Gm" признавалась аккордной, а строка "I Am Boy" нет. При этом порядок может быть разный "Dm B" или "Gm A" и т.д. Ниже прилагают то что удалось сделать мне. Но во-первых, оно почему-то не работает в некоторых строках (быть может они содержат какие-нибудь символы табуляции, переноса строк или еще что-нибудь непечатаемое), а во-вторых способ сам по себе очень громоздкий у меня вышел. Быть может как-то регулярным выражением можно проще это описать? Заранее спасибо. PHP: <?php $txt=nl2br($txt); $textstr=explode("<br />", $txt); $c=count($textstr); for ($i = 0; $i < $c; $i++) { $test=0; $textstr[$i]; $cc=count($textstr); $textstritems=explode(" ", $textstr[$i]); for ($j = 0; $j < $cc; $j++) { if (preg_match("/^Am|B|Gm|D#|Dm$/i",$textstritems[$j]) or $textstritems[$j]=="") { //echo $j.") ".$textstritems[$j]."<br>"; $test=1; //echo "<br>aaa<br>"; } else {$test=0; break;} } if ($test==0) { $txtout.=$textstr[$i]."<br>"; } else { for ($j = 0; $j < $cc; $j++) { $txtout.="<a href=aa>".$textstritems[$j]."</a> "; } $txtout.="<br>"; } } return $txtout; ?>
Ошибка в строках 9-11. 9 строка - ни чего не делает. 10 и 11 надо поменять местами и наверное Код (Text): $cc=count($textstr); надо заменить на Код (Text): $cc=count($textstritems); А вообще интересная задача. Ведь кроме простых A, Am есть еще всякие Asus4, Am7+5 и т. д. Думаю имеет смысл изменить код: PHP: <?php $test=0; $cc=count($textstr); $textstritems=explode(" ", $textstr[$i]); for ($j = 0; $j < $cc; $j++) { if (preg_match("/^Am|B|Gm|D#|Dm$/i",$textstritems[$j]) or $textstritems[$j]=="") { //echo $j.") ".$textstritems[$j]."<br>"; $test=1; //echo "<br>aaa<br>"; } else {$test=0; break;} } ?> на: PHP: <?php $test=1; $textstritems=explode(" ", $textstr[$i]); $cc=count($textstritems); for ($j = 0; $j < $cc; $j++) { if (!isAccord($textstritems[$j])) { $test=0; break; } } ?> И соответственно расписать функцию isAccord($acc)
Упс. Наглядный пример того, что программистов нельзя отвлекать во время составления кода, иначе получаются такие вот глупые ляпы) Спасибо что нашли ошибку. Пишу сайт вместе с человеком который хорошо в этом разибрается. Есть база из 234 аккордов. Гложет только меня сомнение, что сравнение каждого слова текста с таким количеством элементов будет хорошенько грузить сайт... Хотя может и не очень. Попробую завтра что-нибудь состряпать) Просмотрел много зарубежных гитарных сайтов и такое ощущение, что либо в каждой песне модератор вручную аккорды расставляет, либо там какие-то гениальные алгоритмы которые отличают аккорды в любом месте текста.
А в чем сложность? http://amdm.ru/cgen/ Как строится аккорд? - Сначала нота, потом может быть бемоль или диез (а может и не быть), потом может быть то что на амдм назвали "тип" (я без муз. образования, поэтому как это правильно называется не в курсе). Надо просто внимательней почитать как составляются регулярные выражения, например на http://www.pcre.ru/ ну или в вики
Проблема с диезом. Просто диез он не понимает, понимает зато \x23, но только если вокруг него не стоят \b \b (границы слова) Вот к примеру все вариации ноты A. Работает всё кроме A# Код (Text): \b(A|Ab|A\x23)(5|m||6|m6|7|m7|\+7|m\+7|sus2|sus4|9|m9)\b
Первым же делом. Код (Text): \b(A|Ab|A\#)(5|m||6|m6|7|m7|\+7|m\+7|sus2|sus4|9|m9)\b такая конструкция не ловит A#. Или может я неправильно экранирую? Ну можно сделать вместо (A|Ab|A\#) вот так (A)(\#|b||) но сути это особо не изменит, хотя покороче, согласен)
PHP: <?php $chords = array ('C5', 'D#m6', 't123', 'Gb7sus2', 'abc', 'php'); $regexp = '/([A-G][b#]?)(5|m|M|6|m6|7|m7|\+7|m\+7|sus2|sus4|9|m9)?/'; foreach ($chords as $ch) { echo preg_match($regexp, $ch) ? 'true ' : 'false'; echo " - $ch \n"; } ?> Результат: Код (Text): true - C5 true - D#m6 false - t123 true - Gb7sus2 false - abc false - php
Появилась тут проблемка с этим вариантом К примеру вариант A7sdasdasd будет подходить под шаблон, так как preg_match, насколько я понимаю, ищет шаблон внутри строки, а мне нужно чтобы строка целиком совпадала с этим шаблоном. Как это можно реализовать?
Спасибо, помогло. Кстати решил не разделять строки на аккордные и неаккордные, так как слова "I am" почти не встречаются, а вот всякие разные символы и комментарии на строках с аккордами встречаются почти в каждых аккордах и поэтому перестают подсвечиваться.