Javascript 作为开关盒的正则表达式
我有一首歌词,我正在使用一个函数来突出歌词的部分。代码如下所示:Javascript 作为开关盒的正则表达式,javascript,regex,switch-statement,Javascript,Regex,Switch Statement,我有一首歌词,我正在使用一个函数来突出歌词的部分。代码如下所示: var span = { intro : '<span style="color: Magenta ;">', verse : '<span style="color: DodgerBlue;">', prechorus : '<span style="color: DeepPink;">', ch
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);
}
你可以简单地让这个案例通过:
case "[Verse 1]":
case "[Verse 2]":
case "[Verse 3]":
case "[Verse 4]":
case "[Verse 5]": return span.verse + match + span.close; break;
或者您必须使用if…else
语句
case
值可以是任何表达式,但是使用严格的比较将结果与传递给switch
语句的值进行比较,因此您最终将执行/\[Verse.*?\]/g===match
您还可以使用stringmatch
方法。这将使每个案例都与一个正则表达式的标题相匹配。如果标头与正则表达式不匹配,则案例将失败并继续。例如:
case header.match(/\[Verse.*?\]/):return…
查看post,了解如何在切换情况下使用正则表达式的一些示例。使用包含正则表达式的对象,而不是switch语句
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;
}
}
}
});
JSFIDLE示例
Switch语句通常可以用JavaScript中的对象替换。不需要它们。这里可能不需要case语句,甚至不需要lookup对象 如果您可以修改CSS或提供自己的选项来更改选择器,并将内联样式移动到CSS中(它们实际上属于CSS),您可以大大简化为:
function highlight(lyrics) {
return lyrics.replace(/(\[([-a-z]+\b)(?: \d)?\])/gi,'<span class="$2">$1</span>');
}
功能突出显示(歌词){
返回歌词。替换(/(\[([-a-z]+\b)(?:\d)?\])/gi,“$1”);
}
如果A-Z和dash碰巧捕捉到了太多,您可以根据需要收紧正则表达式
如果您想要所有小写的类名,想要将intro和outro合并到一个类中,或者从类名中删除破折号,那么可以使用类似于此替换字符串的回调函数。我会这样做
var html = format( s ,
/\[Verse.*?\]/g, "<span style='color: limegreen;'>@</span>",
/\[Pre-Chorus.*?\]/g, "<span style='color: Magenta;'>@</span>",
/\[Chorus.*?\]/g, "<span style='color: DeepPink;'>@</span>"
);
上面的内容没有经过检验,但我认为这个想法应该很清楚。如果有100首诗呢?有点多余。@Moogs:“或者您必须使用if…else语句。”是否有理由同时使用CSS类和内联样式?您没有访问CSS的权限,并且CSP会阻止自定义CSS源吗?@brianary Nope。我的错误。那是一个古老的剧本。我曾经使用CSS来设置标题的样式。不再是了。我忘了把它们取下来。更新了问题。如果您可以将内联CSS移动到样式表中,或者甚至以编程方式添加样式,这将变得更容易。不管怎样,内联样式的效率和可维护性都较低。是的,我知道。我计划将样式存储在一个对象中,并使用JS添加它们。一旦我正在开发的应用程序完成,我就会这样做。只是这太容易了,我暂时忽略了它=)我曾考虑使用obj来保存正则表达式,但我仍然使用switch语句,并使用函数(作为示例)进行比较。虽然我解决了我的问题,但我不想删除这个问题,以防找到更好的方法。我喜欢你的方法。好多了。但我有一个问题。如果我将regexp对象移动到
highlight
函数之外(使其成为全局),则某些标题不会高亮显示。知道为什么吗?示例:test
在regex对象上设置一个索引,跟踪最后一次匹配。要绕过它,请删除g
标志,或将lastIndex
重置为零,或使用!!match.match(regex)
。让对象在函数中工作,因为它每次都是新对象,所以lastIndex始终为零。我建议删除g标志,因为您真正关心的是是否至少匹配一次。
switch (myVar) {
case 'case1':
/...do work
break
case /[a-z]*/.test(myVar) && myVar:
/...regex match, do work
break
}
function format(s) {
for( var i = 1; i < arguments.length; i += 2 )
if( var m = s.match( arguments[ i ] ) )
return arguments[ i + 1 ].replace("@", m[ 1 ]);
return "";
}
switch (myVar) {
case 'case1':
/...do work
break
case /[a-z]*/.test(myVar) && myVar:
/...regex match, do work
break
}