有这么个需求,将textarea中的重复行去掉。结果将每行join(",")。
最开始拿到这个需求时,想当然的这么写了:
var s ="a\r\na\r\naa\r\nc\r\nc\r\nc\r\n\r\nb\r\nb\r\n";
var o={},//记录不重复的行
arr= s.split(/\r?\n/gi),//取到textarea值时IE中的回车是\r\n,!IE只是\n
i=arr.length,
result="";
while(i--){
if(arr[i] && (!o[arr[i]])) o[arr[i]]=1;
}
for (var k in o ){
if(result!="") result=result+",";
result+=k;
}
alert(result);
没有问题,很常规的做法。后来总想是不是可以用正则去做这个事情,顺便可以温习一下正则,经反复测试,写出了一个下面的代码:
var s ="a\r\na\r\naa\r\nc\r\nc\r\nc\r\n\r\nb\r\nb\r\n";
var regResult =s.replace(/\r?\n/gi,",") // \r\n->,
.replace(/((\,[^\,]+)|(^[^\,]+))(?=((.*\1\,)|(.*\1$)))/gi,"") //去除重复
.replace(/^\,|\,$|\,(?=\,)/gi,"");//去掉多余的,
alert(regResult);
就这么个正则折腾了一上午,当然,字符串也是取了一个比较极端的情况,比如即有a又有aa (行内容包含的情况),3次出现的情况,首尾重复的情况。
去除重复的正则用了宽度断言和反响引用。所谓宽度断言就是可以判断后面/前面的匹配,但是不占用匹配的位置,也就是不影响后面的匹配,他只是一种断言,比如上面的(?=
reg),就是正向宽度断言,能断言后面的出现了之前匹配组内容。反向引用时指可以引用之前匹配的引用组,比如上面的去除重复中的正则\1 就反向应用了第一个匹配组((\,[^\,]+)|(^[^\,]+)) 匹配的内容。
当然,上面的正则肯定不是最优的,希望大家指点了。
可以参考
正则表达式30分钟教程正则的宽度断言
http://deerchao.net/tutorials/regex/regex.htm#lookaround负向宽度断言&反向引用:
http://deerchao.net/tutorials/regex/regex.htm#negativelookaround