[英]How to use a capture group with String.split in old IE versions?
var textt = "L'architecture du système d'information devient";
var pattern = "/(ARCH)/gi";
var array = textt.split(pattern);
console.log(array)
This results in: 结果是:
[
L',
itecture du système d'information devient
]
And the expected result was: 预期结果是:
[
L',
arch,
itecture du système d'information devien
]
Another example 另一个例子
var textt = "ARCHIMAG";
var pattern = "/(ARCH)/gi";
var array = textt.split(pattern);
console.log(array)
Results in: 结果是:
[
IMAG
]
and the expected was: 预期是:
[
ARCH,
IMAG
]
If you're OK with a feature test and function to replace a non–capturing split, try the following. 如果您可以使用功能测试和功能来替换非捕获拆分,请尝试以下操作。 It tests for support when the script is loaded and assigns an appropriate function to nonCaptureSplit , so the test is only done once.
它会在脚本加载时测试是否支持,并将适当的功能分配给nonCaptureSplit ,因此测试仅执行一次。
The pattern will need to be escaped if you are using anything other than alphabetic characters or numerals (eg if there is punctuation in the string). 如果您使用的不是字母字符或数字,则需要转义该模式(例如,如果字符串中有标点符号)。
Now does a completely manual split if lacking support for non-capture split. 如果不支持非捕获拆分,则现在执行完全手动拆分。
// Do case insensitive, non-capture split
var nonCaptureSplit = (function() {
// Feature test for non-capturing split
if ( 'ab'.split(/(a)/).length == 3) {
return function (str, pattern) {
var re = new RegExp('(' + pattern + ')','i');
return str.split(re);
};
// Otherise, do it with a function
} else {
return function(str, pattern) {
// Do case insensitive split
var result = [];
var ts = str.toLowerCase(); // copy of string in lower case
var tp = pattern.toLowerCase();
var first = true;
while (ts.indexOf(tp) != -1) {
var i = ts.indexOf(tp);
// If first match is at the start, insert empty string + pattern
// Trim pattern from front of temp strings
if (i == 0 && first) {
result.push('', pattern);
ts = ts.substring(tp.length);
str = str.substring(tp.length);
// If match is at the end, append pattern and ''
// Set temp string to '' (i.e. finished)
} else if (i == ts.length - tp.length) {
result.push(str.substr(0,i), pattern);
ts = '';
str = '';
// Otherwise, append the next unmatched part
// and pattern
} else {
result.push(str.substring(0,i), pattern);
ts = ts.substring(i + pattern.length);
str = str.substring(i + pattern.length);
}
first = false;
}
// Append remainder of string or '' if used, i.e. last match
// must have been at end of string
result.push( ts.length? str : '');
return result;
};
}
}());
tests: 测试:
alert(nonCaptureSplit('wa', 'wa')); // ,wa,
alert(nonCaptureSplit('qwqwaba', 'wa')); // qwq,wa,ba
alert(nonCaptureSplit('qwqwaba', 'qw')); // ,qw,,qw,aba
alert(nonCaptureSplit('qwqwaba', 'ba')); // qwqwa,ba,
alert(nonCaptureSplit('baaqwqbawaba', 'ba')); // ,ba,aqwq,ba,wa,ba,
alert(nonCaptureSplit("L'architecture du système d'information devient", "ARCH"));
// L',arch,itecture du système d'information devient
alert(nonCaptureSplit("ARCHIMAG", "ARCH")); // ,ARCH,IMAG
It might be a bit inefficient for large strings with lots of matches, but only in browsers without support for non–capturing split. 对于具有大量匹配项的大字符串而言,这可能会有点效率低下,但仅在不支持非捕获拆分的浏览器中。 Test results matched in Safari and IE 6. Please test thoroughly and let me know if there are issues.
测试结果在Safari和IE 6中匹配。请进行彻底测试,并让我知道是否存在问题。
Oh, this isn't a general solution, but it should work for the limited cases similar to the OP. 哦,这不是一个通用的解决方案,但它应适用于类似于OP的有限情况。
If you are looking to get around known browser issues in String.prototype.split
then you need to take a look at Steven Levithan's cross browser fixes And see his original post from back in 2007. This is also used in his XRegExp library . 如果您想解决
String.prototype.split
已知的浏览器问题,那么您需要看一下Steven Levithan的跨浏览器修复程序,并查看他在2007年的原始文章 。XRegExp库中也使用了该文章 。 It is also used in ES5 shim and probably others. 它也用于ES5填充程序 (可能还有其他)中。
/*!
* Cross-Browser Split 1.1.1
* Copyright 2007-2012 Steven Levithan <stevenlevithan.com>
* Available under the MIT License
* ECMAScript compliant, uniform cross-browser split method
*/
/**
* Splits a string into an array of strings using a regex or string separator. Matches of the
* separator are not included in the result array. However, if `separator` is a regex that contains
* capturing groups, backreferences are spliced into the result each time `separator` is matched.
* Fixes browser bugs compared to the native `String.prototype.split` and can be used reliably
* cross-browser.
* @param {String} str String to split.
* @param {RegExp|String} separator Regex or string to use for separating the string.
* @param {Number} [limit] Maximum number of items to include in the result array.
* @returns {Array} Array of substrings.
* @example
*
* // Basic use
* split('a b c d', ' ');
* // -> ['a', 'b', 'c', 'd']
*
* // With limit
* split('a b c d', ' ', 2);
* // -> ['a', 'b']
*
* // Backreferences in result array
* split('..word1 word2..', /([a-z]+)(\d+)/i);
* // -> ['..', 'word', '1', ' ', 'word', '2', '..']
*/
var split;
// Avoid running twice; that would break the `nativeSplit` reference
split = split || function (undef) {
var nativeSplit = String.prototype.split,
compliantExecNpcg = /()??/.exec("")[1] === undef, // NPCG: nonparticipating capturing group
self;
self = function (str, separator, limit) {
// If `separator` is not a regex, use `nativeSplit`
if (Object.prototype.toString.call(separator) !== "[object RegExp]") {
return nativeSplit.call(str, separator, limit);
}
var output = [],
flags = (separator.ignoreCase ? "i" : "") +
(separator.multiline ? "m" : "") +
(separator.extended ? "x" : "") + // Proposed for ES6
(separator.sticky ? "y" : ""), // Firefox 3+
lastLastIndex = 0,
// Make `global` and avoid `lastIndex` issues by working with a copy
separator = new RegExp(separator.source, flags + "g"),
separator2, match, lastIndex, lastLength;
str += ""; // Type-convert
if (!compliantExecNpcg) {
// Doesn't need flags gy, but they don't hurt
separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags);
}
/* Values for `limit`, per the spec:
* If undefined: 4294967295 // Math.pow(2, 32) - 1
* If 0, Infinity, or NaN: 0
* If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
* If negative number: 4294967296 - Math.floor(Math.abs(limit))
* If other: Type-convert, then use the above rules
*/
limit = limit === undef ?
-1 >>> 0 : // Math.pow(2, 32) - 1
limit >>> 0; // ToUint32(limit)
while (match = separator.exec(str)) {
// `separator.lastIndex` is not reliable cross-browser
lastIndex = match.index + match[0].length;
if (lastIndex > lastLastIndex) {
output.push(str.slice(lastLastIndex, match.index));
// Fix browsers whose `exec` methods don't consistently return `undefined` for
// nonparticipating capturing groups
if (!compliantExecNpcg && match.length > 1) {
match[0].replace(separator2, function () {
for (var i = 1; i < arguments.length - 2; i++) {
if (arguments[i] === undef) {
match[i] = undef;
}
}
});
}
if (match.length > 1 && match.index < str.length) {
Array.prototype.push.apply(output, match.slice(1));
}
lastLength = match[0].length;
lastLastIndex = lastIndex;
if (output.length >= limit) {
break;
}
}
if (separator.lastIndex === match.index) {
separator.lastIndex++; // Avoid an infinite loop
}
}
if (lastLastIndex === str.length) {
if (lastLength || !separator.test("")) {
output.push("");
}
} else {
output.push(str.slice(lastLastIndex));
}
return output.length > limit ? output.slice(0, limit) : output;
};
// For convenience
String.prototype.split = function (separator, limit) {
return self(this, separator, limit);
};
return self;
}();
this is the best solution: 这是最好的解决方案:
function ieSplit(str, separator) {
var match = str.match(RegExp(separator, 'g'));
var notmatch = str.replace(new RegExp(separator, 'g'), '[|]').split('[|]');
var merge = [];
for(i in notmatch) {
merge.push(notmatch[i]);
if (match != null && match[i] != undefined) {
merge.push(match[i]);
}
}
return merge;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.