2015-03-19 3 views
5

Я пытаюсь добавить квадратные скобки вокруг аккордов в стандартных текстовых документах, отформатированных для гитары/текстов, чтобы сделать их более совместимыми с приложением OnSong. У меня есть правила, но я не понимаю, как соответствовать всем возможным комбинациям. Правила:Regex для стандартного гитарного лирического/аккордового брекетинга

  • Аккорды начинаются с одного капиталом AG
  • если капитал AG следует пробел, разрыв строку, #, б, м, сус, Август, тусклая, майор, мин, или/я хотел бы прочитать до следующего пробела или разрыва строки (из-за стандартного форматирования гитары, может быть такой аккорд, как F # min/E, и вместо того, чтобы беспокоиться об этом, я просто хочу продолжать чтение до места)
  • Регулярное выражение НЕ должно совпадать, если за столицей AG следует другая буква, не указанная выше (например, имя «Ed» не должно совпадать)
  • бонусные баллы, если вы можете выяснить, как сделать " Маленький мир "НЕ соответствует из-за слова ПОСЛЕДУЮЩЕГО" А ", не являющегося действительным аккордом.
  • супер бонусные баллы, если замена может удалить пространство до (когда не начинается строка), а после новых скобок (чтобы сохранить выравнивание на месте) - мне было указано, что это не удастся на близких аккордах ... это вполне приемлемо.

Пара примечаний: это для вспомогательного сценария ... совершенство не требуется. Я делаю это вручную прямо сейчас, поэтому случайные промахи - все в порядке. Я не пытаюсь разбирать детали аккордов, просто чтобы обернуть их в []. В то время как стандартная компоновка - это 1 ряд аккордов, 1 ряд текстов, на это нельзя рассчитывать, поэтому я знаю, что некоторые сценарии не срабатывают изредка.

источник испытания (аккорды случайны для целей тестирования, в случае, если какие-либо музыканты собирались перезвон в на страшной музыке):

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 

должен превратиться в:

[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 

Моей первую попытку меня закрыли:

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

но это взяло слова, которые начинались с этих букв как Что ж. Я пошел вокруг в кругах сейчас и только получили, насколько:

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

Когда я пытался использовать [^\s+] я получаю смешанные результаты, которые улавливают больше того, что я хочу, но и канаву, что мне нужно. Кажется, я чуть выше головы. Любая помощь была бы высоко оценена, и любое объяснение того, как она работает, будет еще лучше. Хотя я бы хотел найти решение, я также очень хотел бы объяснить, почему это работает ...

+0

Так 'A # Eb // О человек' будет '[A #] [Eb] // О человек'!? Из-за близости этих аккордов мы теряем выравнивание (добавление скобок). – zessx

+0

Хорошая точка на аккордах прямо друг против друга ... иногда выравнивание просто не работает - я принял эту судьбу :) – IglooWhite

+0

С каким языком или инструментом вы будете использовать регулярное выражение? И что это за животное? –

ответ

5

Это проходит с помощью ввода пробы и достигает все ваше «супер бонусного очко» Требования:

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

Этот код превращает это (в виде одной строки со встроенными сборами линии):

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 

В этом документе:

[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

Очень круто - неужели он не поддерживает выравнивание в начале? – IglooWhite

+0

Нет - как вы можете видеть на выходе, вся строка аккорда набросилась на один символ справа, вставив '[' в начале. Чтобы этого избежать, нужно было бы использовать дополнительное пространство (т.е. 2 пробела) после аккорда в начале строки. Хотя, честно говоря, выравнивание отлично смотрится с помощью '[' now marking the start of chord - возможно, просто используйте его как есть. Кстати, вы можете найти Apache commons-io 'FileUtils.readFileToString()' и 'writeStringToFile()' handy – Bohemian

2

У меня есть рабочее регулярное выражение для случая, которое вы предоставили, но не знаете, как он будет работать для других. Проблема в том, что строка может начинаться с A, или она может быть в линии песни. Я попытался обойти это, используя отрицательную проверку, если за аккордом следует пробел и буквенно-цифровое выражение. Если есть пробел и буквенно-цифровой символ, мы не согласуем этот аккорд. Поскольку аккорды могут повторяться после /, я удваиваю шаблон.

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

Посмотрите the demo.

+0

Это действительно отлично. Я добавляю параметр «m», который я тоже забыл. '([CDEFGAB] (б ?: | бб | м) * ((<= \ б?):? # | ## | SUS | Maj | мин | август) * [\ d \ /] * (: [ CDEFGAB] (б ?: | бб | м) *? (?: # | ## | SUS | Maj | мин | август) * [\ d \ /] *) *) (= \ s | $) (?! \ w) ' – IglooWhite

+0

Имейте в виду, что может возникнуть проблема, если между аккордами есть только 1 пробел. Возможно, мы можем сделать это более безопасным с '(?! [^ CDEFGAB])' lookahead. –

+0

fyi '(? <= \ B)' одинаково - это просто '\ b', так как ни один из них не потребляет вход. Также это будет соответствовать «Aaugmin» или A ####### - использовать? вместо * – Bohemian

0

код выполняет соглашение в образце, который я проверил, и Соглашение s simplesles 7th соглашения с острым или плоским, как 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 это вопрос * java * – Bohemian

+0

@ Эрик странно, другой пользователь добавил Java в микс, так как мой вопрос был действительно общая проблема с регулярным выражением. Я понимаю, что замена в конце требует выбора языка, но любой мог бы это сделать. Тем не менее, я думаю, что это слишком усложняет настоящую потребность ... поскольку я не пытаюсь доказать недействительные аккорды (dim35 или тому подобное), здесь происходит много дополнительной проверки. Вероятно, это было бы действительно полезно, если бы кто-то собирался разбирать детали. – IglooWhite

0

Я улучшил немного ответа от предыдущего ответа, чтобы помочь в моем случае. Теперь он игнорировал некоторые «аккорды», если он находится в начале стиха (например, A, E). Это то, что я вышел:

(\(*[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])