$.trim()
использует следующий RegExp для обрезки строки:
/^(\s|\u00A0)+|(\s|\u00A0)+$/g
Как оказалось, это может быть довольно ужасно, Пример:
var mystr = ' some test -- more text new test xxx';
mystr = mystr.replace(/^(\s|\u00A0)+|(\s|\u00A0)+$/g, "");
Этот код подвешивает Firefox и Chrome, он просто берет как навсегда".mystr
"содержит пробелы, но главным образом hex 160(A0)
персонажи. Эта "проблема" действительно только происходит, если нет никакого предварительного ожидания whitespace/A0
, но где-нибудь в строке. У меня нет подсказки, почему это происходит.
Это выражение:
/^[\n\r\t \xA0]+|[\n\r\t \xA0]$/g
просто хорошо работает во всех протестированных сценариях. Возможно, лучший шаблон для этого?
Источник: http://code.jquery.com/jquery-1.4.2.js
ОБНОВЛЕНИЕ
Похоже, что Вы не можете copy&paste эта строка в качестве примера в некоторых точках они A0
символы заменяются. Firebug console
также заменит символы на вставке, необходимо создать собственную строку в sepperate файле/редакторе HTML для тестирования этого.
Это известная ошибка, как сказано в комментариях, и Crescent прав в том, что это так в 1.4.2, но это уже исправлено в следующем релизе.
Вы можете проверить скорость работы String.prototype.trim
на вашей строке здесь: http://jsfiddle.net/dLLVN/
Я получаю около 79 мс в Chrome 117 мс в Firefox для миллиона запусков... так что это исправит проблему зависания :)
Что касается исправления, взгляните на текущий исходник, который будет в 1.4.3, теперь используется родная обрезка.
В марте было 2 коммита для этого:
trim: function( text ) {
return (text || "").replace( rtrim, "" );
},
//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, "" );
}
Значения trimLeft
и trimRight
меняются в зависимости от того, в 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]+$/;
}
Обычно выражения типа ^ \ s + | \ s + $
должно быть достаточно для обрезки, поскольку \ s
должен соответствовать всем пробелам, четные \ 0xa0
неразрывные пробелы 1 . Это выражение должно выполняться без каких-либо проблем.
Возможно, какой-то браузер, который хочет поддерживать jQuery, не соответствует \ 0xa0
с \ s
, и для решения этой проблемы jQuery добавил альтернативу (\ s | \ 0xa0)
, чтобы удалить неразрывные пробелы и в этом браузере.
С этим изменением вторая часть регулярного выражения выглядит как (\ s | \ 0xa0) + $
, что приводит к проблемам в браузерах, где \ 0xa0
также соответствует \ s
. В строке, содержащей длинную последовательность символов \ 0xa0
, каждому символу может соответствовать \ s
или \ 0xa0
, что приводит к множеству альтернативных совпадений и экспоненциально много комбинаций, как можно комбинировать разные совпадения. Если эта последовательность \ 0xa0
символов не находится в конце строки, конечное условие $
никогда не может быть выполнено, независимо от того, какие пробелы соответствуют \ s
и которые соответствуют \ 0xax
, но браузер не знает этого и пробует все комбинации, потенциально ища очень долго.
Предложенного вами упрощенного выражения будет недостаточно, поскольку \ s
должен соответствовать всем символам пробела Юникода, а не только хорошо известным символам ASCII.
1 Согласно MDC , \ s
эквивалентно [\ t \ n \ v \ f \ r \ u00a0 \ u2000 \ u2001 \ u2002
Как оказалось, это поведение было опубликовано в багтрекере jQuerys месяц назад:
http://dev.jquery.com/ticket/6605
Спасибо Эндрю
за указание на меня к тому, что.