Javascript и регулярное выражение: разделите строку и сохраните разделитель
У меня есть строка:
var string = "aaaaaa<br />† bbbb<br />‡ cccc"
И я хотел бы разделить эту строку с разделителем <br />
, за которым следует специальный символ.
Для этого я использую это:
string.split(/<br \/>&#?[a-zA-Z0-9]+;/g);
Я получаю то, что мне нужно, за исключением того, что теряю разделитель.
Вот пример: http://jsfiddle.net/JwrZ6/1/
Как сохранить разделитель?
Ответы
Ответ 1
Используйте положительный lookahead, чтобы регулярное выражение утверждало, что специальный символ существует, но на самом деле не соответствует ему:
string.split(/<br \/>(?=&#?[a-zA-Z0-9]+;)/g);
Посмотрите на действие.
Обновление: фиксированная опечатка (перемещенный литерал ;
внутри lookahead parens)
Ответ 2
У меня была схожая, но небольшая проблема. Во всяком случае, здесь приведены примеры трех разных сценариев, где можно сохранить разделитель.
"1、2、3".split("、") == ["1", "2", "3"]
"1、2、3".split(/(、)/g) == ["1", "、", "2", "、", "3"]
"1、2、3".split(/(?=、)/g) == ["1", "、2", "、3"]
"1、2、3".split(/(?!、)/g) == ["1、", "2、", "3"]
"1、2、3".split(/(.*?、)/g) == ["", "1、", "", "2、", "3"]
Предупреждение: Четвертый будет работать только для разделения отдельных символов. ConnorsFan представляет альтернативу:
// Split a path, but keep the slashes that follow directories
var str = 'Animation/rawr/javascript.js';
var tokens = str.match(/[^\/]+\/?|\//g);
Ответ 3
Если вы заключите разделитель в скобки, он будет частью возвращаемого массива.
string.split(/(<br \/>&#?[a-zA-Z0-9]+);/g);
// returns ["aaaaaa", "<br />†", "bbbb", "<br />‡", "cccc"]
В зависимости от того, какую часть вы хотите сохранить, какую подгруппу вы соответствуете
string.split(/(<br \/>)&#?[a-zA-Z0-9]+;/g);
// returns ["aaaaaa", "<br />", "bbbb", "<br />", "cccc"]
Вы можете улучшить выражение, игнорируя случай букв String.split(/() & # [а-z0-9] +;?/ги);
И вы можете сопоставить такие предопределенные группы следующим образом: \d
equals [0-9]
и \w
equals [a-zA-Z0-9_]
. Это означает, что ваше выражение может выглядеть так.
string.split(/<br \/>(&#?[a-z\d]+;)/gi);
Существует хорошая ссылка регулярного выражения на JavaScriptKit.
Ответ 4
ответил также здесь Раскройте регулярное выражение JavaScript Splititer
используйте шаблон (? = pattern) lookahead в регулярном выражении
Пример
var string = '500x500-11*90~1+1';
string = string.replace(/(?=[$-/:-?{-~!"^_`\[\]])/gi, ",");
string = string.split(",");
это даст вам следующий результат.
[ '500x500', '-11', '*90', '~1', '+1' ]
Можно также напрямую разделить
string = string.split(/(?=[$-/:-?{-~!"^_`\[\]])/gi);
дает тот же результат
[ '500x500', '-11', '*90', '~1', '+1' ]
Ответ 5
Функция расширения разделяет строку с подстрокой или RegEx, а разделитель помещается по второму параметру вперед или назад.
String.prototype.splitKeep = function (splitter, ahead) {
var self = this;
var result = [];
if (splitter != '') {
var matches = [];
// Getting mached value and its index
var replaceName = splitter instanceof RegExp ? "replace" : "replaceAll";
var r = self[replaceName](splitter, function (m, i, e) {
matches.push({ value: m, index: i });
return getSubst(m);
});
// Finds split substrings
var lastIndex = 0;
for (var i = 0; i < matches.length; i++) {
var m = matches[i];
var nextIndex = ahead == true ? m.index : m.index + m.value.length;
if (nextIndex != lastIndex) {
var part = self.substring(lastIndex, nextIndex);
result.push(part);
lastIndex = nextIndex;
}
};
if (lastIndex < self.length) {
var part = self.substring(lastIndex, self.length);
result.push(part);
};
// Substitution of matched string
function getSubst(value) {
var substChar = value[0] == '0' ? '1' : '0';
var subst = '';
for (var i = 0; i < value.length; i++) {
subst += substChar;
}
return subst;
};
}
else {
result.add(self);
};
return result;
};
Тест:
test('splitKeep', function () {
// String
deepEqual("1231451".splitKeep('1'), ["1", "231", "451"]);
deepEqual("123145".splitKeep('1', true), ["123", "145"]);
deepEqual("1231451".splitKeep('1', true), ["123", "145", "1"]);
deepEqual("hello man how are you!".splitKeep(' '), ["hello ", "man ", "how ", "are ", "you!"]);
deepEqual("hello man how are you!".splitKeep(' ', true), ["hello", " man", " how", " are", " you!"]);
// Regex
deepEqual("mhellommhellommmhello".splitKeep(/m+/g), ["m", "hellomm", "hellommm", "hello"]);
deepEqual("mhellommhellommmhello".splitKeep(/m+/g, true), ["mhello", "mmhello", "mmmhello"]);
});
Ответ 6
Я использовал это:
String.prototype.splitBy = function (delimiter) {
var
delimiterPATTERN = '(' + delimiter + ')',
delimiterRE = new RegExp(delimiterPATTERN, 'g');
return this.split(delimiterRE).reduce((chunks, item) => {
if (item.match(delimiterRE)){
chunks.push(item)
} else {
chunks[chunks.length - 1] += item
};
return chunks
}, [])
}
За исключением того, что вы не должны путаться с String.prototype
, поэтому здесь есть версия функции:
var splitBy = function (text, delimiter) {
var
delimiterPATTERN = '(' + delimiter + ')',
delimiterRE = new RegExp(delimiterPATTERN, 'g');
return text.split(delimiterRE).reduce(function(chunks, item){
if (item.match(delimiterRE)){
chunks.push(item)
} else {
chunks[chunks.length - 1] += item
};
return chunks
}, [])
}
Итак, вы можете сделать:
var haystack = "aaaaaa<br />† bbbb<br />‡ cccc"
var needle = '<br \/>&#?[a-zA-Z0-9]+;';
var result = splitBy(string, haystack)
console.log( JSON.stringify( result, null, 2) )
И вы получите:
[
"<br />† bbbb",
"<br />‡ cccc"
]
Ответ 7
function formatDate(dt, format) {
var monthNames = [
"Enero", "Febrero", "Marzo",
"Abril", "Mayo", "Junio", "Julio",
"Agosto", "Setiembre", "Octubre",
"Noviembre", "Diciembre"
];
var Days = [
"Domingo", "Lunes", "Martes", "Miercoles",
"Jueves", "Viernes", "Sabado"
];
function pad(n, width, z) {
z = z || '0';
n = n + '';
return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}
function replace(val, date) {
switch (val) {
case 'yyyy':
return date.getFullYear();
case 'YYYY':
return date.getFullYear();
case 'yy':
return (date.getFullYear() + "").substring(2);
case 'YY':
return (date.getFullYear() + "").substring(2);
case 'MMMM':
return monthNames[date.getMonth()];
case 'MMM':
return monthNames[date.getMonth()].substring(0, 3);
case 'MM':
return pad(date.getMonth() + 1, 2);
case 'M':
return date.getMonth() + 1;
case 'dd':
return pad(date.getDate(), 2);
case 'd':
return date.getDate();
case 'DD':
return Days[date.getDay()];
case 'D':
return Days[date.getDay()].substring(0, 3);
case 'HH':
return pad(date.getHours(), 2);
case 'H':
return date.getHours();
case 'mm':
return pad(date.getMinutes(), 2);
case 'm':
return date.getMinutes();
case 'ss':
return pad(date.getSeconds(), 2);
case 's':
return date.getSeconds();
default:
return val;
}
}
var ds = format.split(/( |,|:)/g);
var newFormat = '';
for (var i = 0; i < ds.length; i++) {
newFormat += replace(ds[i], dt);
}
return newFormat;
}
var a = "2016-08-22T16:02:05.645Z";
var d = new Date(Date.parse(a));
// var d = new Date();
console.log(formatDate(d, 'd de MMMM, de YYYY H:mm'));