OsakaWebbie
Programmer
Yeah, I know the subject line is cryptic... I have a database that keeps song lyrics with chords interspersed within square brackets, like this:
I allow the user to search for text in the lyrics, so I have to somehow get past the chords. The code in use has been there for quite a while, and I thought it worked, but I recently discovered that it doesn't always. Since MySQL doesn't have a way to remove the bracketed content on the fly using regex, I was attacking it from the opposite direction, using PHP to create a regex expression from the search string, like this (search string is "leaving" in this example):
That technique seems to work if the chord(s) within the matching section of lyrics are only a single letter (e.g. "o my father", "and leav", and "work on earth" work fine), but if there are multiple characters inside the brackets, the matching record is not returned. I thought the "*" in my regex would take care of that, but it doesn't seem to. Does someone see what I'm missing, or have a better approach?
It would be cleaner with something like "WHERE LOWER(REGEXP_REPLACE(Lyrics,'(\\[[^\\]]*\\])','')) LIKE '%leaving%'", but although there seem to be two offerings of a UDF for regex replace out there (here and here), both are very old and not maintained, and I don't know if they will even work with newer versions of MySQL. Plus, one requires recompiling MySQL and the other slightly less invasive but still requires compiling itself and has dependencies. If you know that one or both of those do work okay, or know of something else, let me know. I would prefer to use what is already a part of the engine, though, if I can figure out how.
Code:
[D]Thank you, [D/F#]O my [G]Fa[D]ther, for [G]giving us [A]Your [D A]Son
And [D]leav[A/E]ing [D/F#]Your [G]Spirit [D/F#]till the [Em]work on [A]earth is [D]done
Code:
WHERE LOWER(Lyrics) REGEXP '(\\[[^\\]]*\\])?l(\\[[^\\]]*\\])?e(\\[[^\\]]*\\])?a(\\[[^\\]]*\\])?v(\\[[^\\]]*\\])?i(\\[[^\\]]*\\])?n(\\[[^\\]]*\\])?g'
It would be cleaner with something like "WHERE LOWER(REGEXP_REPLACE(Lyrics,'(\\[[^\\]]*\\])','')) LIKE '%leaving%'", but although there seem to be two offerings of a UDF for regex replace out there (here and here), both are very old and not maintained, and I don't know if they will even work with newer versions of MySQL. Plus, one requires recompiling MySQL and the other slightly less invasive but still requires compiling itself and has dependencies. If you know that one or both of those do work okay, or know of something else, let me know. I would prefer to use what is already a part of the engine, though, if I can figure out how.