JavaScript split string by positive lookbehind

Viewed 364

I'm trying to split a string including the delimeters, so for example

  • "a/b/c" would become ["a/", "b/", "c"]
  • "a//b" would become ["a/", "/", "b"]

var s = "a/b/c".split(/(?<=\/)/);

console.log(s); // prints ["a/", "b/", "c"]

It works perfectly fine in Chrome, but Firefox says: SyntaxError: invalid regexp group

Hence my questions:

  1. Is the code legal?
  2. How to make it work in Firefox and Edge?
3 Answers

I don't think Firefox supports lookbehinds yet. Instead, you can split using a capture group to retain the delimiter, match any preceding characters that are not forward slashes within the group, and then filter to remove the empty strings. For example:

const s = 'a/b/c'.split(/([^/]*\/)/).filter((x) => x);
console.log(s);
// ["a/", "b/", "c"]

const s = 'a//b'.split(/([^/]*\/)/).filter((x) => x);
console.log(s);
// ["a/", "/", "b"]

(a) it looks like most browsers don't yet support lookbehind; Chrome is one of the few that do (as of 2019-Jun) [source: http://kangax.github.io/compat-table/es2016plus/#test-RegExp_Lookbehind_Assertions ]

(b) I would tend to simply split by /\//, and know that every element but the last should "really" have a trailing slash. "a/b//c//".split(/\//) returns ["a","b","","c","",""].

(c) You could also do a match (rather than split) on "slash, followed by 0-or-more-non-slashes: "a/b//c//".match(/[^\/]*\//g) returns ["a/","b/","/","c/","/"].

Btw, be sure to test your solution on strings that start with a "/" (which should presumably return just "/" as the very first element).

I don't know why that thing doesn't work in rest of the browsers. But you can use following trick with replace:

var text = 'a/b/c';
var splitText = text
    .replace(new RegExp(/\//, 'g'), '/ ') // here you are replacing your leading slash `/` with slash + another symbol e.g. `/ `(space is added) 
    .split(' ') // to further split with added symbol as far as they are removed when splitting.
 console.log(splitText) // ["a/", "b/", "c"]

In this way you can avoid using that complex regExp which doesn't work in FireFox, Edge etc.

Related