jQuerys $ .trim(),bug还是编写不好?

jAn*_*ndy 9 javascript regex jquery

$.trim() 使用以下RegExp修剪字符串:

/^(\s|\u00A0)+|(\s|\u00A0)+$/g
Run Code Online (Sandbox Code Playgroud)

事实证明,这可能非常难看,例如:

var mystr = '    some test --          more text            new test                                         xxx';
mystr = mystr.replace(/^(\s|\u00A0)+|(\s|\u00A0)+$/g, "");
Run Code Online (Sandbox Code Playgroud)

这段代码挂起了 Firefox和Chrome,它就像永远一样." mystr"包含空格,但主要是hex 160(A0)字符.这个"问题"只会发生,如果没有前置whitespace/A0,但在字符串中的某个地方.我不知道为什么会这样.

这个表达式:

/^[\n\r\t \xA0]+|[\n\r\t \xA0]$/g
Run Code Online (Sandbox Code Playgroud)

在所有测试场景中都能正常工作.也许是一个更好的模式?

来源:http://code.jquery.com/jquery-1.4.2.js

UPDATE

看起来你不能复制和粘贴这个示例字符串,在某些点上这些A0字符被替换.Firebug console也将替换粘贴上的字符,你必须在一个sepperate html文件/编辑器中创建自己的字符串来测试它.

Nic*_*ver 9

这是一个已知的错误,如评论中所述,而Crescent在1.4.2中就是这样,但它已经在下一个版本中得到修复.

你可以String.prototype.trim在这里测试你的字符串的速度:http://jsfiddle.net/dLLVN/
我在Chrome浏览器中获得了大约79ms,在Firefox中运行了一百万次...所以这将解决悬挂问题:)

至于修复,看一下将在1.4.3中的当前源,现在使用原生修剪.

3月份有2次提交:


1.4.2 $.trim()功能:

trim: function( text ) {
    return (text || "").replace( rtrim, "" );
},
Run Code Online (Sandbox Code Playgroud)

1.4.3 $.trim()功能:

//earlier: 
trim = String.prototype.trim

//new trim here
trim: trim ?
  function( text ) {
    return text == null ?
      "" : 
      trim.call( text ); 
  } :

  // Otherwise use our own trimming functionality
  function( text ) { 
    return text == null ? 
      "" :
      text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
  }
Run Code Online (Sandbox Code Playgroud)

trimLefttrimRight各不相同,这取决于您是否是在IE或没有,像这样:

trimLeft = /^\s+/,
trimRight = /\s+$/,

// Verify that \s matches non-breaking spaces
// (IE fails on this test)
if ( !/\s/.test( "\xA0" ) ) {
  trimLeft = /^[\s\xA0]+/;
  trimRight = /[\s\xA0]+$/;
}
Run Code Online (Sandbox Code Playgroud)


sth*_*sth 7

通常情况下,表达式^\s+|\s+$应足以进行修剪,因为\s它应该匹配所有空格字符,甚至是\0xa0不间断的空格1.此表达式应该运行而不会导致任何问题.

现在可能是jQuery想要支持的一些浏览器\0xa0\s这个问题不匹配并且解决这个问题jQuery添加了替代方案(\s|\0xa0),以便在该浏览器上删除不间断的空间.

有了这个改变,正则表达式的第二部分看起来像(\s|\0xa0)+$,这导致浏览器中的问题\0xa0也匹配\s.在包含长\0xa0字符序列的字符串中,每个字符可以与\s或匹配\0xa0,从而导致许多替代匹配和指数级多种组合如何组合不同的匹配.如果这个顺序\0xa0字符是不是在字符串的结尾,结尾$条件不能满足,无论哪个空间被匹配\s和被匹配\0xax,但浏览器并不知道这一点,并尝试所有的组合,可能搜索很长一段时间

你建议的简化表达式是不够的,因为\s它应该匹配所有unicode空格字符,而不仅仅是众所周知的ASCII字符.


1根据MDC,\s相当于[\t\n\v\f\r \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000]


jAn*_*ndy 5

事实证明,这个行为是在一个月前发布在jQuerys bugtracker上的:

http://dev.jquery.com/ticket/6605

感谢您Andrew指点我.