如何将foo\nbar\baz
之类的javascript字符串拆分为一系列行,同时保留换行符?我希望['foo\n', 'bar\n', 'baz']
作为输出;
我知道有很多可能的答案 - 我只是很想找到一个时髦的答案。
使用perl我会使用zero-width lookbehind assertion:split /(?<=\n)/
,但javascript正则表达式不支持它们。
PS。处理不同行结尾(至少\r\n
)和处理丢失的最后一个换行符的额外点(如我的例子中所示)。
答案 0 :(得分:5)
您可以使用此模式执行全局匹配:/[^\n]+(?:\r?\n|$)/g
它匹配任何非换行符,然后匹配可选的\r
后跟\n
或字符串的结尾。
var input = "foo\r\n\nbar\nbaz";
var result = input.match(/[^\n]+(?:\r?\n|$)/g);
结果:["foo\r\n", "bar\n", "baz"]
答案 1 :(得分:2)
怎么样?
"foo\nbar\nbaz".split(/^/m);
结果
["foo
", "bar
", "baz"]
答案 2 :(得分:0)
一个简单但粗略的方法是首先用2个特殊字符替换“\ n”。拆分第二个,并在拆分后用“\ n”替换第一个。不高效而不优雅,但绝对有效。
答案 3 :(得分:0)
由于IE的实现失败,我会使用正则表达式远离split
。请改用match
。
'foo\n\bar\n\baz".match(/^.*(\r?\n|$)/mg)
结果:["foo\n", "bar\n", "baz"]
答案 4 :(得分:0)
评论中的其他答案和答案都有不同的缺陷。我需要一个可以在任何字符串或文件上正常工作的函数。
这是一个简单而正确的答案:
function split_lines(s) {
return s.match(/[^\n]*\n|[^\n]+/g);
}
input = "foo\r\n\nbar\n\r\nba\rz\r\r\r";
a = split_lines(input);
Array(5) [ "foo\r\n", "\n", "bar\n", "\r\n", "ba\rz\r\r\r" ]
它有效地在每个换行符\n
处分割,但包含\n
,并且当且仅当不为空时,它包含最后一行且不尾随\n
。它在输出中包括所有输入字符。 \r
不需要任何特殊待遇。
我已经对大量随机数据进行了测试,它确实保留了所有输入字符,\n
仅出现在行尾。
这是一个测试脚本:
function split_lines(s) {
return s.match(/[^\n]*\n|[^\n]+/g);
}
function gen_random_string(n, ncharset=256, nlprob=0.05, crprob=0.05) {
var s = "";
for (let i = 0; i < n; ++i) {
var r = Math.random();
if (r < nlprob)
s += "\n";
else if (r < nlprob + crprob)
s += "\r";
else {
var cc = Math.floor(r / (1 - nlprob - crprob) * ncharset);
var c = String.fromCharCode(cc);
s += c;
}
}
return s;
}
function test(...args) {
var s = gen_random_string(...args);
console.log(`generated random string of length ${s.length} with args:`, ...args);
var ok = true, ok1;
var a = split_lines(s);
console.log(`split into ${a.length} lines`);
ok1 = s === a.join('');
ok = ok && ok1;
console.log("split lines combine to give the original string?", ok1 ? "OK" : "FAIL");
for (var i = 0; i < a.length; ++i) {
var s1 = a[i];
ok1 = s1.endsWith("\n") || i == a.length-1;
ok = ok && ok1;
ok1 = !s1.slice(0, -1).includes("\n");
ok = ok && ok1;
}
console.log("tested each line other than the last ends with \\n");
console.log("tested each line does not contain \\n before the last character");
console.log("Final result", ok ? "OK" : "FAIL");
}
test(10000, 256);
test(10000, 65536);