每一个小鸟都很愤怒,因为我们还不会分组作战
我们还是用小鸟们做例子,来学会使用分组
var str =
'【红色小鸟】(红火)体型小,重量轻,攻击弱,无特效,可在滚动时消灭绿猪。适合攻击玻璃与木头,攻击混凝土较弱。(关卡1-1)\n【蓝色小鸟】(蓝冰)体型极小,重量轻,攻击弱,可以变成3个。攻击玻璃较强,攻击木头与混凝土较弱。(关卡1-10)';
str.match(/^(【[\u4e00-\u9fa5]+】)(([\u4e00-\u9fa5]+))([\u4e00-\u9fa50-9,。]+)([\u4e00-\u9fa5]+(\d+\-\d+))$/gm);
str.split(/^(【[\u4e00-\u9fa5]+】)(([\u4e00-\u9fa5]+))([\u4e00-\u9fa50-9,。]+)([\u4e00-\u9fa5]+(\d+\-\d+))$/gm);
我们希望把格式变成
"【红色小鸟】的外号是(红火),出现在关卡1-1\n【蓝色小鸟】的外号是(蓝冰),出现在关卡1-10"
分析字符串
- 需要进行多行全局搜索,前后需要无字符,所以要用上
gm^$
。 - 需要取出名字,【[\u4e00-\u9fa5]+】
- 需要拿到外号,([\u4e00-\u9fa5]+)
- 需要拿到能力,[\u4e00-\u9fa50-9,。]+
- 需要拿到关卡,[\u4e00-\u9fa5]+(\d+-\d+)
把以上拼接在一起就是
/^(【[\u4e00-\u9fa5]+】)(([\u4e00-\u9fa5]+))([\u4e00-\u9fa50-9,。]+)([\u4e00-\u9fa5]+(\d+\-\d+))$/gm
分组能干嘛呢
我们知道()是用来分组的,可是分组有什么用呢。上面分别给2,3,4,5步的正则都加上了()。我们可以在string的replace函数中使用分组。看一下这个代码。
str.replace(/^(【[\u4e00-\u9fa5]+】)(([\u4e00-\u9fa5]+))([\u4e00-\u9fa50-9,。]+)([\u4e00-\u9fa5]+(\d+\-\d+))$/gm, "$1的外号是$2,出现在关卡$4");
这样我们的目的已经达到了,输出了"【红色小鸟】的外号是(红火),出现在关卡1-1\n【蓝色小鸟】的外号是(蓝冰),出现在关卡1-10"
。
不捕获的分组
我们可以注意到上面使用$4
引用到了关卡,如何使用$3
就引用到呢?
str.replace(/^(【[\u4e00-\u9fa5]+】)(([\u4e00-\u9fa5]+))(?:[\u4e00-\u9fa50-9,。]+)([\u4e00-\u9fa5]+(\d+\-\d+))$/gm, "$1的外号是$2,出现在关卡$3");
?:
表示不捕获的分组,我们在能力分组上(?:[\u4e00-\u9fa50-9,。]+)
加上了不捕获的标志。
好用的工具
一旦正则表达式复杂起来,很难看懂,这时候利用一些工具则非常有用
上面这个网站可以用来分析正则表达式。有高亮的功能哦。可惜对中文支持的不是很好。