Regex for standard guitar lyric / chord bracketing

I am trying to add square brackets around chords in standard text documents formatted for guitar / text to make them more compatible with the OnSong app. I have rules, but I don’t understand how to match all possible combinations. Rules:

  • Chords start from the same capital AG
  • if the capital of AG is followed by a space, line break, #, b, m, sus, aug, dim, maj, min or / I would like to read it until the next space or line break (due to standard guitar formatting, there may be such a chord, like F # min / E, and instead of worrying about it, I just want to keep reading until the place).
  • The regular expression must NOT match if the capital of AG is followed by another letter that is not listed (for example, the name "Ed" must not match)
  • bonus points if you can understand how to make the “small world” NOT suitable because of the word “FOLLOW” that “A” is not a valid chord.
  • super bonus points, if the substitution can remove the space before (when the line does not start), and after new brackets (to keep the alignment in place) - I was told that this will not work on close chords ... this is quite acceptable.

A few notes: this is for a helper script ... perfection is not required. I'm doing it manually right now, so random misses are all right. I am not trying to disassemble the details of chords, just to wrap them in []. While the standard layout is 1 row of chords, 1 row of lyrics, this cannot be taken into account, so I know that some scenarios will sometimes fail.

Testing source (chords are random for testing purposes, in case some musicians are going to listen to terrible music):

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

Should turn into:

 [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 

My first attempt closed me:

 ([AG]((?!\s).)*) 

but it raised words that began with these letters. Now I went around in circles and only got to:

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

When I tried to use [^\s+] , I get mixed results that take away more of what I want, but also what I need. I seem to be just above my head. Any help would be greatly appreciated, and any explanation of how it works would be even better. Although I would like to find a solution, I would also really like to explain why it works ...

+5
source share
4 answers

This goes through your input pattern and reaches all your “super bonus points" requirements:

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

This code turns this (as a single String with a built-in price):

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

In it:

 [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 
+5
source

I have some working regex for the case you provided, but don't know how it will work for others. The problem is that the line may begin with A , or it may be in the line of the song. I tried to get around this using a negative check if the chord is followed by a space and an alphanumeric expression. If there is a space and an alphanumeric character, we do not agree on this chord. Since chords can be repeated after / , I double the pattern.

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

Check out the demo .

+2
source

the code successfully fulfills the agreement in the test sample, and the agreements mimic the 7th agreement with a clear or flat like C # 7

 string strRegex = @"^[AG]([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])?([\/][AG]([5679bm#])?([57])?)?"; Regex myRegex = new Regex(strRegex, RegexOptions.None); string strTargetString = @"A"; string strReplace = @"[$0]"; return myRegex.Replace(strTargetString, strReplace); 
0
source

I slightly improved the answer from the previous answer to help in my case. Now he has ignored some “chords” if he is at the beginning of the verse (for example, A, E). This is what I went out:

 (\(*[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|$])(?! [az]) 
0
source

Source: https://habr.com/ru/post/1215681/


All Articles