Say I have a string __f__g_f_
How can I achieve splitting it up to an array like ['__','f','__','g','_','f','_']
Say I have a string __f__g_f_
How can I achieve splitting it up to an array like ['__','f','__','g','_','f','_']
This should do:
const str = '__f__g_f_'
const parts = str.split(/([a-z]+)/)
console.log(parts)
Instead of using .split() you can use .match() with a matching group in the regex, it will give you an array of all your wanted matches.
const str = '__f__g_f_'
const parts = str.match(/(_+)|([a-z]+)/g)
console.log(parts);
[
"__",
"f",
"__",
"g",
"_",
"f",
"_"
]
Split works at O(N) time complexity so you can write your own implementation and it is more readable and more maintainable
const s = "__f__g_f_"
const array = []
let buffer = ""
for (let i = 0; i < s.length; i++) {
if (s[i] === "_") {
buffer += s[i]
continue
}
if (buffer.length > 0) {
array.push(buffer)
buffer = ""
}
array.push(s[i])
}
if (buffer.length > 0) {
array.push(buffer)
}
console.log(array)
Edit:
(/([a-z]+)/) is elegant but always be in the shoes of other developers. What does (/([a-z]+)/) mean at a glance ? Regex is like a compiled program, machine code. unless all developers are adept in regex, They are not self-documented. They require to be commented on. And there might have bugs in them, how can you trust /([a-z]+)/ if it actually works without running the code? Seeing human readable code is always preferable. And finally, you may be surprised that regex can have weird time complexity, sometimes they jump to exponential. You don't know how they are implemented. Here, a simple plain and readable implementation is 100% faster than the regex.
console.time('regex');
for (let i = 0; i < 100_000_000; i++) {
const str = '__f__g_f_'
const parts = str.split(/([a-z]+)/)
}
console.timeEnd("regex")
console.time('plain_fast');
for (let i = 0; i < 100_000_000; i++) {
const s = "__f__g_f_"
const array = []
let buffer = ""
for (let i = 0; i < s.length; i++) {
if (s[i] === "_") {
buffer += s[i]
continue
}
if (buffer.length > 0) {
array.push(buffer)
buffer = ""
}
array.push(s[i])
}
if (buffer.length > 0) {
array.push(buffer)
}
}
console.timeEnd("plain_fast")
regex: 10540.700ms
plain_fast: 4556.500ms
Here is a custom function without regex.
function split(str) {
let output = []
let cur = ''
for(let i = 0; i < str.length; i++) {
if(str[i] !== '_') {
output.push(str[i])
continue;
}
cur += str[i]
if(str[i + 1] !== '_') {
output.push(cur)
cur = ''
}
}
return output
}
console.log(split('__f__g_f_'))