实现去除字符串两端空白(相当于trim)功能的正则表达式/^\s*((.|\n)*\S)?\s*$/

Wind__Fantasy 2011-06-07 01:04:57
实现去除字符串两端空白(相当于trim)功能的正则表达式/^\s*((.|\n)*\S)?\s*$/
javascript代码:
    String.prototype.trim = function () {  
return this.replace(/^\s*((.|\n)*\S)?\s*$/, '$1' );
}
/* for example: */ alert(' a b c '.trim());
// 或
function trim(str) {
return str.replace(/^\s*((.|\n)*\S)?\s*$/, '$1' );
}
/* for example: */ alert(trim(' a b c '));




现在解释正则表达式/^\s*((.|\n)*\S)?\s*$/,
很明显, 首先你应该知道上面的正则表达式是匹配任何字符串的, 所以总能将目标字符串替换成$1(意识到这点很重要) ,
(1)、如果字符串中至少有一个非空白字符, /^\s*((.|\n)*\S)?\s*$/将与/^\s*((.|\n)*\S)\s*$/等价
A.首先因为^\s*后没有紧跟?(即^\s*?), 所以正则表达式^\s*尝试贪婪地(尽可能多地)匹配目标字符串中以0或多个空白字符开始的字符 , 匹配开始的所有空白字符结束后,
B.然后匹配((.|\n)*\S)?, 因为上面假设了至少有一个非空白字符, 所以((.|\n)*\S)整体即便不要紧跟后面的?也总能匹配, 而且\S总能匹配从头到尾的最后一个非空白字符 , 这里要注意(.|\n)能匹配任何字符, 要知道句点字符.匹配任何非换行符\n的字符. 接着我们想要的结果(这儿是任何以非空白字符开始非空白字符结束的字符串, 因为开始的空白字符已经被A贪婪了, 而结束的非空白字符是匹配\S的字符, (.|\n)*虽然很贪婪, 但它会留一个给\S的以保证匹配 )会被存放到$1中, 而最后一次在\S前一个匹配的任意字符(.|\n)会放在$2中
C.紧接着\S后的空白字符都会匹配, 但不是想要的
(2)、否则 字符串中都是空白字符, 那么它尝试匹配/^\s*((.|\n)*\S)?\s*$/ 时, (.|\n)*\S将得不到匹配, 但由于((.|\n)*\S)?会得到匹配(匹配空串), 所以会将$1设为空串, 执行字符串替换时会将整个匹配的字符串替换成空串, 这不正是我们想要的么?

解决这个问题有两个难点就是:

1、匹配的长度不好判断 , 比如/^\s*((.|\n)*)\s*$/, 因为((.|\n)*)是贪婪的, 所以它会匹配几乎所有字符, 然后最多会留给\s*$一个字符匹配(因为匹配\s的肯定匹配(.|\n), 而(.|\n)*是贪婪的), 然后将((.|\n)*)改成((.|\n)*?)这样不是贪婪的但匹配的又太少, 必须要选择合适的模式((.|\n)*\S)?既不能匹配过长, 也不能匹配过短

2、应该尝试构造一个能够匹配任何字符串的正则表达式, 然后去提取需要的部分 , 去除字符串两端空白后肯定是原字符串的某部分, 所以应该尝试提取该部分进行替换, 如果你构造了一个并不总是匹配源字符串的正则表达式, 比如/^\s*((.|\n)*\S)\s*$/(它 不匹配字符串' ', 那么它将不会得到处理, 这也就是为什么会是((.|\n)*\S)?, 因为要为这种情况考虑 ), 那么源字符串将得不到替换, 这点很重要,至少构造这样一个(替换)正则表达式: "当源字符串不匹配它时(这时字符串替换将失败), 它匹配由非空白字符开始和结束的字符串(这样才可以不进行替换) "应该会很有挑战!

你可以测试上述正则表达式像这样: alert('*' + teststr.replace(/^(\s*)((.|\n)*\S)?(\s*)$/, '[ ($1) ($2) ($3)($4) ]') + '*') , 其中teststr是待trim的字符串, 而加上*是为了知道字符串的开始是否含空格, 同样的道理对应($1)神马的, 所以你的teststr最好不要有[(*等字符干扰结果, 如果你对$1神马的不懂, 去翻翻正则表达式或javascript手册这个例子的确没多大现实意义, 因为绝大多数程序设计语言都提供了trim函数, 而且明显地即便没提供实现它也很easy, 使用正则的确大材小用了, 但是透过这个例子至少你进一步学习了正则, 而且我几乎可以保证应该没人会像我这般无聊去用正则写trim, 哈哈

有感于以前装(11+15)/2做项目时不用常规的trim算法(两端逐个剔除空白字符))而非用正则表达式写trim(因为javascript里貌似没有trim必须自己写), 而且悲剧的是还写错了: str.replace(/^(\s*)(\S*)(\s*)$/, '$2'); // 今天才想起来过去好像写错了, 惭愧...

大家若有更好的正则方法, 请告知, 若我写的正则有问题, 也请告知, 3q

今晚要考C++了, 希望可以考高分, 顺便祝那些即将高考的孩子们考出好成绩, 高考结束后慎重些填志愿, 别被学校名骗了...
...全文
675 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
hch126163 2012-11-02
  • 打赏
  • 举报
回复
/^\s*|\s*$/

匹配开始空白 和结束空白
_轻薄的假象_ 2012-11-02
  • 打赏
  • 举报
回复
我又纠结了 貌似lz的也不行啊 你的那个好像是直接替换 不管是不是空白
猿敲月下码 2012-11-02
  • 打赏
  • 举报
回复
<高性能javascript>一书中有提到关于trim的方法,也列举了几种方法.并且对比了它们的效率

楼主感兴趣的话可以看看
_轻薄的假象_ 2012-11-02
  • 打赏
  • 举报
回复
坑爹啊 我用“/^\s*|\s*$/g” 这个一直去除java中返回的json中字符串, 一直去不掉 找了两个多小时就是死活不匹配 用了楼主的就可以了 这究竟是为啥子呐
madpc 2011-06-07
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 jparser 的回复:]

" abcd 123 ".replace(/^\s*|\s*$/g,"")
[/Quote]

正解
Wind__Fantasy 2011-06-07
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 lxcnn 的回复:]

引用楼主 wind__fantasy 的回复:
实现去除字符串两端空白(相当于trim)功能的正则表达式/^\s*((.|\n)*\S)?\s*$/


这个未免效率太低了吧
[/Quote]
主要是用来学习正则的,多一种方法不是更好么?虽然效率低,但可能会给解决其他问题带来启示
q107770540 2011-06-07
  • 打赏
  • 举报
回复
同意LS意见
-过客- 2011-06-07
  • 打赏
  • 举报
回复
[Quote=引用楼主 wind__fantasy 的回复:]
实现去除字符串两端空白(相当于trim)功能的正则表达式/^\s*((.|\n)*\S)?\s*$/
[/Quote]

这个未免效率太低了吧
JParser 2011-06-07
  • 打赏
  • 举报
回复
" abcd 123 ".replace(/^\s*|\s*$/g,"")
bhbhxy 2011-06-07
  • 打赏
  • 举报
回复
学习了,一直很疑惑这个字符串是什么意思
xuexueCN 2011-06-07
  • 打赏
  • 举报
回复
replace(/(^\s*)|(\s*$)/,"");
这就可以
wuwu8ku 2011-06-07
  • 打赏
  • 举报
回复

trim : function(str){ /*删除首尾相应内容,参数为空则删除空格*/
var reg;
if(str){
str = str.replace(/([\.\+\?\*\\\^\&\[\]\(\)\{\}\$\,])/g,'\\$1');
reg = new RegExp("^(" + str +")+|(" + str + ")+$","g");/* 特殊字符 (. + ? * \ ^ & [ ] ( ) { } $ ,) */
}else{
reg = /^\s+|\s+$/g;
}
return this.replace(reg,"");
}

87,910

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧