You may match any text up to an CRLF or LF or end of string:
text.match(/.*(?:$|\r?\n)/g).filter(Boolean)
// -> (4) ["↵", " first ↵", " second ↵", " third"]
The .*(?:$|\r?\n)
pattern matches
.*
- any 0 or more chars other than newline
(?:$|\r?\n)
- either end of string or an optional carriage return and a newline.
JS demo:
console.log("\r\n first \r\n second \r\n third".match(/.*(?:$|\r?\n)/g));
console.log("\n first \r\n second \r third".match(/.*(?:$|\r?\n)/g));
console.log("\n\n\n first \r\n second \r third".match(/.*(?:$|\r?\n)/g));
For ECMAScript 2018 standard supporting JS environments, it is as simple as using a lookbehind pattern like
text.split(/(?<=\r?\n)/)
It will split at all positions that immediately follow an optional CR + LF symbol.
Another splitting regex is /^(?!$)/m
:
console.log("\r\n first \r\n second \r\n third".split(/^(?!$)/m));
console.log("\n first \r\n second \r third".split(/^(?!$)/m));
console.log("\n\n\n first \r\n second \r third".split(/^(?!$)/m));
Here, the strings are split at each position after a CR or LF that are not at the end of a line.
Note you do not need a global modifier with String#split
since it splits at all found positions by default.