2

I just learned the hard way that negative lookbehinds are not supported in firefox. Just deployed to production and all seemed fine. Once our firefox users started hitting it, they got nothing.

Is there a pollyfill or some alternative to this regex?

"Item 1, Item2^, Item2a, Item3".split(/(?<!\^),/)

I am trying to split a string into arrays on a commas but not on ^,

"Item 1, Item2^, Item2a, Item3"

Should end up as

[
"Item 1",
"Item2^, Item2a",
"Item3"
]
mwilson
  • 12,295
  • 7
  • 55
  • 95
  • 1
    They're not generally supported in any JavaScript environment other than Chrome, as far as I know currently. – Pointy Jun 13 '19 at 17:29
  • Yea, I get that. That's why I'm asking to see if there's a different method/regex I can use. – mwilson Jun 13 '19 at 17:40
  • 1
    I'd also have an idea using `match` like `var res = str.match(/(?:[^\^,]+|\^(?!,)|\^,)+/g);` but you'd need to trim spaces at start/end if there are any ([see pattern](https://regex101.com/r/tuvhgr/1)). – bobble bubble Jun 13 '19 at 22:12

2 Answers2

2

As an alternative, there's always good old "double replacement" for you:

r = "Item 1, Item2^, Item2a, Item3"
  .replace(/,/g, '~')
  .replace(/\^~/g, '^,')
  .split(/~ /g)
 
console.log(r)

Basically, /(?<! X) Y/ is "unrolled" into three steps:

  • replace Y => temp
  • replace X temp back to X Y
  • now temp is what you want
georg
  • 211,518
  • 52
  • 313
  • 390
  • 1
    @IceMetalPunk: sure, choose the temp char wisely. – georg Jun 13 '19 at 17:34
  • There are super-great temp characters in Unicode: the [non-characters](http://www.unicode.org/faq/private_use.html#nonchar1) -- I like `u+FDD[123]`, in javascript `\xFDD1` – Stephen P Jun 13 '19 at 21:53
  • Ended up going with this as the other solutions involve a large regex that I really don't want to troubleshoot if something else were to pop up. Although slightly 'ghetto', this is much more readable and maintainable. – mwilson Jun 14 '19 at 01:27
2

As said in the comments JS doesn't support lookbehinds in the old EmcaScript version.
The new version (6 I think does support it).

No matter, what you can do is a find all regex that matches what you need.

Find /\s*((?:(?!\s*(?:,|$))[^,\^])*(?:\^,?(?:(?!\s*(?:,|$))[^,\^])*)*)\s*,?\s*/g

Where the element is in capture group 1 every match.
Note this regex does whitespace trimming, otherwise it would be very small.

Readable regex

 \s* 
 (                             # (1 start)
      (?:
           (?! \s* (?:,|$) )
           [^,\^] 
      )*

      (?:
           \^,?
           (?:
                (?! \s* (?:,|$) )
                [^,\^] 
           )*
      )*
 )                             # (1 end)
 \s* 
 ,?
 \s* 

JS Demo

var arr = [];
var str = "Item 1, Item2^, Item2a, Item3  ,,, ii , kkk ";
var re = /\s*((?:(?!\s*(?:,|$))[^,\^])*(?:\^,?(?:(?!\s*(?:,|$))[^,\^])*)*)\s*,?\s*/g;

str.replace( re, function( m, grp1 ) {
     arr.push( grp1 );
    });

console.log( arr );
  • I really like this one, I'm going to save this link I'll use this several times in the future. –  Jun 13 '19 at 21:00