php regex guitar tab (sekme veya tablature, müzik notasyonu bir tür)

3 Cevap php

PHP (Zil Sesi Metin Aktarım Dili) dönüştürücü RTTTL bir gitar tab oluşturma sürecinde yaşıyorum. Ben her şeyden önce yorum (- ve ile sona erdi - yorumlar no not #) dışarı şerit rtttl dönüşüm için bir gitar tab hazırlamak için, ben, sonra tempoyu ayarlamak birkaç satır var tunning not ve birden aletleri (Tempo 120 \ tanımlamak sekmesinin dışarı çıkardı ve daha sonra kullanılmak üzere kenara koyun nDefine Guitar 1 \ nDefine Bass 1, vs vs).

Şimdi ben aslında gitar sekmeleri dışında hiçbir şeyim kalmadı. Her sekme enstrüman adı ile birlikte bu enstrüman adı ile öneki öncesinde kaydetti.

Birlikte çalınacak çünkü biz bağlantılı 2 ayrı enstrümanlar için sekmeler var bazı zamanlar, bir gitar ve birlikte oynayan Bas Gitar yani.

Örnek 1, Standart Gitar Tab:

 |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--|

Örnek 2, Bağlaç Tab:

 |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--|

Ben sağlam sonuçlar hiçbir ile sekmeleri tanımlayan diğer yöntemleri kabul var. Ben normal ifadeler yapan birisi bana bir tek gitar tab tanımlamak için bir yol bulmak ve mümkünse aynı zamanda birbirine bağlı birden fazla enstrümanlar ile bir sekme maç mümkün olabileceğini umuyorum.

Sekmeleri bir dizide bir kez ben bir zamanda onlarla bir satır gidin ve ("n \" her yeni satırda patladı) rtttl hatlarına dönüştürmek olacaktır.

Değil sekmelerde kendilerini - Ben oldukça, bu sekmeler arasında boşluk tanımlarken, gitar tab tespit değil çünkü "\ n \ n" veya benzer bir şey patlayabilir yoluyla belgede gitar sekmeleri ayırmak istemiyorum.

Şimdi yaklaşık bir hafta boyunca bu karıştırmasını olmuştur ve bu ben tek büyük kadar beklemeye. Her şey oldukça basittir.

Akım gibi, ben regex desen birçok varyasyonlar denedi. İşte En son test örneklerinden biridir:

<?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);

?>

Bu çizgi ve # 'ler vardır sekmeler, iç, sen de harfler, sayılar ve noktalama işaretlerinden herhangi bir varyasyonu olabileceğini de fazlalaştı. A, a #, b, c, c #, d, d #, e, f, f # g veya g: Her satırın başında duyarsız aşağıdaki durum biri ile her bir dize ayarlama işaretler.

Bu en zor sorunu yardım için şimdiden teşekkür ederiz.

3 Cevap

<?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;

$t = preg_replace('/\r\n?/', "\n", $t); //normalize line endings

$te = explode("\n", $t);

$out = array();
$cur_inst = "";
$trim = false;
$lastlines = array();
$i = 0;
foreach ($te as $line) {
    if (preg_match("/^\\s\\|(\\w+ \\d+)\$/", $line, $matches)) {
        if ($matches[1] == $cur_inst) {
            $trim = true;
        }
        else {
            $out[$i++] = $line;
            $trim = false;
            $lastline = array();
            $cur_inst = $matches[1];
        }
    }
    elseif (empty($line) || preg_match("/^\\s\\|\$/", $line)) {
        if (!preg_match("/^\\s\\|\$/", end($out)))
            $out[$i++] = $line;
    }
    elseif (preg_match("/^([a-zA-Z])\\|(.*)\$/", $line, $matches)) {
        if ($trim) {
            if (array_key_exists($matches[1], $lastlines)) {
                $oldi= $lastlines[$matches[1]];
                $out[$oldi] = rtrim($out[$oldi], "|") . $matches[2];
            }
            else {
                die("unexpected line: $line");
            }
        }
        else {
            $lastlines[$matches[1]] = $i;
            $out[$i++] = $matches[0];
        }
    }
    else {
        die("unexpected line: $line");
    }
}

$t = implode(PHP_EOL, $out);

echo $t;

verir

 |Guitar 1
e|--------------3-------------------3--------------------------3-------------------3------------|
B|------------3---3---------------3---3----------------------3---3---------------3---3----------|
G|----------0-------0-----------0-------0------------------0-------0-----------0-------0--------|
D|--------0-----------0-------0-----------0--------------0-----------0-------0-----------0------|
A|------2---------------2---2---------------2----------2---------------2---2---------------2----|
E|----3-------------------3-------------------3------3-------------------3-------------------3--|

 |
 |Bass 1
G|----------0-------0-----------0-------0--------|
D|--------2-----------2-------2-----------2------|
A|------3---------------3---3---------------3----|
E|----3-------------------3-------------------3--|

Eğer tercih ederseniz, $out dizi üzerinden yineleme yapabilirsiniz.

Ben ne demek istediğini tamamen emin değilim, ama cihaz tarafından sekmeleri ayırmak istiyorsanız, bu deneyin:

^[^|\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];
}

Her maç formda olacaktır

 |Bass 1
G|----------0-------0-----------0-------0--------|
D|--------2-----------2-------2-----------2------|
A|------3---------------3---3---------------3----|
E|----3-------------------3-------------------3--|

ve bu bloklar arasında her şeyin göz ardı edilecektir.

^ Senin regex istediğiniz ne yapıyorsun / s anahtarını önleyecektir.

Ayrıca, preg_match_all sen () gruplama kullanarak çünkü yinelenen "Karşılaşmalar" bir sürü geri gidiyor. Gerçek sonuç izole, birden fazla sekme ile bir dosya üzerinde preg_match_all () kullanmayı planlıyorsanız bu çiftleri ile zor olabilir.