2015-03-19 8 views
5

Próbuję dodać nawiasy kwadratowe wokół akordów w standardowych dokumentach tekstowych sformatowanych dla gitary/słów, aby były bardziej kompatybilne z aplikacją OnSong. Mam zasady, ale nie rozumiem, jak dopasować wszystkie możliwe kombinacje. Zasady są:Regex dla standardowego uchwytu lirycznego/akordowego

  • Akordy rozpocznie jednym AG kapitału
  • jeśli AG kapitału następuje przestrzeni, linia przerwy, #, b, m, sus, sierpień, słabe, Maj, min, lub/Chciałbym czytać do następnej przerwy lub linii (ze względu na standardowe formatowanie gitary możliwe jest użycie akordu takiego jak F # min/E, a nie kłopotliwe dzielenie go na całość, chcę tylko zachować czytanie do miejsca)
  • Nie można dopasować wyrażenia regularnego, jeśli po kapitale występuje inna litera, która nie znajduje się na powyższej liście (na przykład nazwa "Ed" nie powinna pasować)
  • punktów bonusowych, jeśli potrafisz wymyślić, jak zrobić " Mały świat NIE pasuje do słowa NASTĘPUJĄC, że "A" nie jest prawidłowym akordem.
  • superpunktowe punkty, jeśli zamiennik może usunąć spację przed (kiedy nie zaczyna linii) i po nowych nawiasach (w celu utrzymania wyrównania na miejscu) - zostało mi wskazane, że to się nie powiedzie w przypadku bliskich akordów ... jest to całkowicie do przyjęcia.

Kilka notatek: To jest dla skryptu pomocnika ... doskonałość nie jest potrzebna. Robię to ręcznie teraz, więc od czasu do czasu chybienie jest w porządku. Nie próbuję analizować szczegółów akordów, tylko je zawijać []. Podczas gdy standardowy układ to 1 rząd akordów, 1 wiersz tekstu, nie można na to liczyć, więc zdaję sobie sprawę, że niektóre scenariusze czasami się nie udają.

źródło Test (akordy są przypadkowe w celach testowych, w przypadku jakichkolwiek muzycy jechali kurant na strasznej muzyki):

Db Dsus4/F#   A   Cbmin/C 
A man can't be asked for that much to do 
D/F#  G   A   D#/E 
And I can't sweep you off of your feet 

powinien przekształcić:

[Db] [Dsus4/F#]   [A]   [Cbmin/C] 
A man can't be asked for that much to do 
[D/F#]  [G]  [A]   [D#/E] 
And I can't sweep you off of your feet 

moja pierwsza próba zbliżyli mnie do siebie:

([A-G]((?!\s).)*) 

, ale to podniosło słowa, które zaczęły się tymi literami także. I już w kółko i dopiero teraz dostał miarę:

\b([CDEFGAB](#|##|b|bb|sus|maj|min|aug)?\b) 

Kiedy próbowałem użyć [^\s+] mam mieszane wyniki podnieść więcej od tego, co chcę, ale również rowu rzeczy, których potrzebuję. Myślę, że jestem po prostu nad głową. Każda pomoc byłaby WSPANIAŁA doceniona, a wszelkie wyjaśnienia, jak to działa, byłyby jeszcze lepsze. Podczas gdy chciałbym rozwiązania, również bardzo chciałbym wyjaśnić, dlaczego to działa ...

+0

Więc 'A # Eb // Oh man' 'będzie [A #] [Eb] // Oh man'! Ze względu na bliskość tych akordów tracimy wyrównanie (dodając nawiasy). – zessx

+0

Dobry punkt na akordy wprost przeciwko sobie ... czasami wyrównanie po prostu nie zadziała - zaakceptowałem ten los :) – IglooWhite

+0

Z jakim językiem lub narzędziem użyjesz regex? A czym jest to zwierzę? –

Odpowiedz

5

To przechodzi za pomocą wejścia próbki i osiąga wszystkie swoje „Super punktów bonusowych” Wymagania:

String output = input.replaceAll("(?m)(^|)([A-G](##?|bb?)?((sus|maj|min|aug|dim)\\d?)?(/[A-G](##?|bb?)?)?)((?!\\w)|$)", "[$2]"); 

Ten kod zamienia ten (jako jeden ciąg znaków z wbudowanymi opłat Line):

Db Dsus4/F#   A   Cbmin/C 
A man can't be asked for that much to do 
D/F#  G   A   D#/E 
And I can't sweep you off of your feet 

W tym:

[Db] [Dsus4/F#]   [A]   [Cbmin/C] 
A man can't be asked for that much to do 
[D/F#]  [G]  [A]   [D#/E] 
And I can't sweep you off of your feet 
+0

bardzo fajnie - czy to NIE zachowuje wyrównania na początku? – IglooWhite

+0

Nie - jak widać na wyjściu, cała linia akordów jest uderzona o jeden znak po prawej przez wstawienie '[' na początku. Aby tego uniknąć, trzeba by zająć dodatkową przestrzeń (tj. 2 spacje) za akordem na początku linii. Chociaż szczerze mówiąc, wyrównanie wygląda dobrze z "[teraz oznaczającym początek akordu - może po prostu użyj go tak, jak jest. BTW możesz znaleźć Apache commons-io 'FileUtils.readFileToString()' i 'writeStringToFile()' poręczny – Bohemian

2

Mam pewne robocze wyrażenie regularne dla sprawy, które podałeś, ale nie wiesz, jak to będzie działać dla innych. Problem polega na tym, że linia może zaczynać się od A lub może znajdować się w linii utworu. Próbowałem obejść to za pomocą negatywnego sprawdzania z wyprzedzeniem, jeśli po akordzie występuje spacja i alfanumeryczny. Jeśli jest spacja i alfanumeryczny, nie pasujemy do tego akordu. Ponieważ akordy powtarzają się po /, podwaja to wzór.

\b([CDEFGAB](?:b|bb)*(?:#|##|sus|maj|min|aug)*[\d\/]*(?:[CDEFGAB](?:b|bb)*(?:#|##|sus|maj|min|aug)*[\d\/]*)*)(?=\s|$)(?! \w)

Wystarczy popatrzeć na the demo.

+0

To jest naprawdę doskonałe. Dodaję w opcji "m", o której też zapomniałem. '(? <= \ b) ([CDEFGAB] (?: b | bb | m) * (?: # | ## | sus | maj | min | aug) * [\ d \ /] * (?: [ CDEFGAB] (?: b | bb | m) * (?: # | ## | sus | maj | min | aug) * [\ d \ /] *) *) (? = \ S | $) (?! \ w) ' – IglooWhite

+0

Pamiętaj, że może wystąpić problem, jeśli między akordami jest tylko 1 spacja. Być może, możemy uczynić to bezpieczniejszym z '(?! [^ CDEFGAB])' uprzedzeniem. –

+0

fyi '(? <= \ B)' jest identyczne to po prostu '\ b', ponieważ żaden z nich nie zużywa wejścia. Również pasowałoby to do "Aaugmin" lub A ####### - use? zamiast * – Bohemian

0

kod wykonuje umowę dobrze w próbce, którą sprawdziłem i Agreem Zawiera 7 umów z ostrymi lub płaskimi jak C# 7

string strRegex = @"^[A-G]([5679bm#]([57])?|1[13]|6\/9|7[-#+b][59]|7?sus[24]|add[249]|aug|dim7?|m\/maj7|m1[13]|m[679]|m7?b5|maj1[13]|maj[79])?([\/][A-G]([5679bm#])?([57])?)?"; 

Regex myRegex = new Regex(strRegex, RegexOptions.None); 
string strTargetString = @"A"; 
string strReplace = @"[$0]"; 

return myRegex.Replace(strTargetString, strReplace); 
+0

fyi to jest * java * pytanie – Bohemian

+0

@Eric dziwnie, inny użytkownik dodał Java do miksu, ponieważ moje pytanie było naprawdę ogólny problem z Regeksem. Rozumiem, że podstawienie na końcu wymaga wyboru języka, ale każdy może naprawdę to zrobić. To powiedziawszy, myślę, że to nadmiernie komplikuje prawdziwą potrzebę ... ponieważ nie próbuję udowodnić nieważnych akordów (dim35 lub tym podobne), jest tu dużo dodatkowych sprawdzeń. Byłoby to bardzo przydatne, gdyby ktoś chciał przeanalizować szczegóły. – IglooWhite

0

Ulepszyłem nieco odpowiedź z poprzedniej odpowiedzi, aby pomóc w moim przypadku. Teraz ignorowało niektóre "akordy prawdopodobne", gdy znajduje się na początku wersetu (jak A, E). To co mi wyszło:

(\(*[CDEFGAB](?:b|bb)*(?:#|##|sus|maj|min|aug|m|M|°|[0-9])*[\(]?[\d\/]*[\)]?(?:[CDEFGAB](?:b|bb)*(?:#|##|sus|maj|min|aug|m|M|°|[0-9])*[\d\/]*)*\)*)(?=[\s|$])(?! [a-z])