I have a song lyrics and I'm using a function to highlight the parts of the lyrics. The code looks like this:
var span = {
intro : '<span style="color: Magenta ;">',
verse : '<span style="color: DodgerBlue;">',
prechorus : '<span style="color: DeepPink;">',
chorus : '<span style="color: Tomato;">',
bridge : '<span style="color: LimeGreen;">',
outro : '<span style="color: Magenta ;">',
repeat : '<span style="color: Silver;" title="Repeat">',
close : '</span>',
};
function highlight(lyrics) {
var highlighted = lyrics.replace(/\[.*\]/g, function(match) {
switch(match) {
case "[Intro]": return span.io + match + span.close; break;
case "[Verse 1]": return span.verse + match + span.close; break;
case "[Verse 2]": return span.verse + match + span.close; break;
case "[Verse 3]": return span.verse + match + span.close; break;
case "[Verse 4]": return span.verse + match + span.close; break;
case "[Verse 5]": return span.verse + match + span.close; break;
case "[Pre-Chorus 1]": return span.prechorus + match + span.close; break;
case "[Pre-Chorus 2]": return span.prechorus + match + span.close; break;
case "[Pre-Chorus 3]": return span.prechorus + match + span.close; break;
case "[Pre-Chorus 4]": return span.prechorus + match + span.close; break;
case "[Chorus 1]": return span.chorus + match + span.close; break;
case "[Chorus 2]": return span.chorus + match + span.close; break;
case "[Chorus 3]": return span.chorus + match + span.close; break;
case "[Chorus 4]": return span.chorus + match + span.close; break;
case "[Chorus 5]": return span.chorus + match + span.close; break;
case "[Bridge 1]": return span.bridge + match + span.close; break;
case "[Bridge 2]": return span.bridge + match + span.close; break;
case "[Outro]": return span.io + match + span.close; break;
}
});
return highlighted.replace(/\(R.{0,3}\)/g, span.repeat + "$&" + span.close);
}
highlight function expects a text. First, it finds the strings (headers of lyrics parts) that are enclosed by brackets, then using switch, it checks the found matches and wraps them in a corresponding span tag.
My problem is that I don't want to use five different cases to replace verses, or any other repeating headers. Instead I want to use a regexp. Something like:
case /\[Verse.*?\]/g: return span.verse + match + span.close; break;
Fiddle
Use an object holding the regular expressions, instead of a switch statement.
var highlighted = lyrics.replace(/\[.*\]/g, function (match) {
var regex = {
intro: /\[Intro.*?\]/g,
verse: /\[Verse.*?\]/g,
prechorus: /\[Pre-Chorus.*?\]/g,
chorus: /\[Chorus.*?\]/g,
bridge: /\[Bridge.*?\]/g,
outro: /\[Outro.*?\]/g
};
for (var k in regex) {
if (regex.hasOwnProperty(k)) {
if (regex[k].test(match)) {
return span[k] + match + span.close;
}
}
}
});
JSFiddle example
http://jsfiddle.net/unwthvns/1/
Switch statements can usually always be replaced with an object in JavaScript. No need for them.
You could also use the string match method. This would have each case match the header against a regex. If the header does not match the regex, the case will fail and move on. For example:
case header.match(/\[Verse.*?\]/): return ...
Check out this post for some examples of how to use regular expressions in switch cases.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With