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

实现去除字符串两端空白(相当于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++了, 希望可以考高分, 顺便祝那些即将高考的孩子们考出好成绩, 高考结束后慎重些填志愿, 别被学校名骗

了…

点赞