Javascript и регулярное выражение: разделить строку и сохранить разделитель
у меня есть строка:
var string = "aaaaaa<br />† bbbb<br />‡ cccc"
и я хотел бы разделить эту строку с разделителем <br />
за ним следует специальный символ.
чтобы сделать это, я использую это:
string.split(/<br />&#?[a-zA-Z0-9]+;/g);
Я получаю то, что мне нужно, за исключением того, что я теряю разделитель. Вот пример: http://jsfiddle.net/JwrZ6/1/
как я могу сохранить разделитель?
6 ответов:
использовать позитивный просмотр вперед так что регулярное выражение утверждает, что существует специальный символ, но на самом деле не соответствует это:
string.split(/<br \/>(?=&#?[a-zA-Z0-9]+;)/g);
увидеть его в действии:
var string = "aaaaaa<br />† bbbb<br />‡ cccc"; console.log(string.split(/<br \/>(?=&#?[a-zA-Z0-9]+;)/g));
обновление: исправлена опечатка (перемещенный литерал
;
внутри lookahead parens)
у меня была похожая, но небольшая другая проблема. В любом случае, вот примеры трех различных сценариев для того, где хранить разделитель.
"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);
если вы обернете разделитель в parantheses, он будет частью возвращаемого массива.
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"]
вы можете улучшить выражение, игнорируя регистр букв строка.split (/()?[a-z0-9]+;/gi);
и вы можете соответствовать для предопределенных групп такой:
\d
равна[0-9]
и\w
равна[a-zA-Z0-9_]
. Это означает, что ваше выражение может выглядеть так этот.string.split(/<br \/>(&#?[a-z\d]+;)/gi);
есть хорошая ссылка на регулярное выражение на JavaScriptKit.
ответил он и здесь регулярное выражение JavaScript Split сохраняет разделитель
использовать (?=pattern) lookahead pattern в регулярном выражении пример
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' ]
функция расширения разделяет строку с подстрокой или регулярным выражением, и разделитель ставится в соответствии со вторым параметром впереди или позади.
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"]); });
я использую этот:
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" ]