Вот один вкладыш:
str.match(/\n\n|(?:[^\n]|\n(?!\n))+/g)
Вот как это работает:
\n\n
соответствует двум последовательным символам новой строки
(?:[^\n]|\n(?!\n))+
соответствует любой последовательности из одного или нескольких символов
[^\n]
не символ новой строки или
\n(?!\n)
символ новой строки, но только если за ним не следует другой символ новой строки
Этот рекурсивный шаблон может быть применен к любой длине:
// useful function to quote strings for literal match in regular expressions
RegExp.quote = RegExp.quote || function(str) {
return (str+"").replace(/(?=[.?*+^$[\]\\(){}|-])/g, "\\");
};
// helper function to build the above pattern recursively
function buildRecursivePattern(chars, i) {
var c = RegExp.quote(chars[i]);
if (i < chars.length-1) return "(?:[^" + c + "]|" + c + buildRecursivePattern(chars, i+1) + ")";
else return "(?!" + c + ")";
}
function buildPattern(str) {
return RegExp(RegExp.quote(delimiter) + "|" + buildRecursivePattern(delimiter.match(/[^]/g), 0) + "+", "g");
}
var str = 'hello world\n\nbye world\n\nfoo\nbar\n\nfoo\nbaz\n\n',
delimiter = "\n\n",
parts;
parts = str.match(buildPattern(delimiter))
Обновление Вот модификация для String.prototype.split
, которая также должна добавить возможность содержать соответствующий разделитель:
if ("a".split(/(a)/).length !== 3) {
(function() {
var _f = String.prototype.split;
String.prototype.split = function(separator, limit) {
if (separator instanceof RegExp) {
var re = new RegExp(re.source, "g"+(re.ignoreCase?"i":"")+(re.multiline?"m":"")),
match, result = [], counter = 0, lastIndex = 0;
while ((match = re.exec(this)) !== null) {
result.push(this.substr(lastIndex, match.index-lastIndex));
if (match.length > 1) result.push(match[1]);
lastIndex = match.index + match[0].length;
if (++counter === limit) break;
}
result.push(this.substr(lastIndex));
return result;
} else {
return _f.apply(arguments);
}
}
})();
}