Gazz
Gazz

Reputation: 1075

JS regex: Alternative for positive / negative lookbehind

I'm having issues with the following regex working in Safari and so am having to change how I approach this regex. I need the following regex to only select the text between: cp1= and |.

For example if I had this string:

firstName=John|lastName=Smith|cp1=/en-gb/|age=30

I'd only want to get /en-gb/ and nothing else.

The following JS works below in all browsers i've tested except for Safari:

// if myString = firstName=John|lastName=Smith|cp1=/en-gb/|age=30
let currentCP1Value = myString.match(/(?<=cp1=)(.*)(?=\|)|(?<=cp1=).*(?<!a)$/); // outputs /en-gb/

This is due to the positive/negative lookbehind's used in the regex. What would be the alternative to this to get this working in Safari?

Upvotes: 0

Views: 117

Answers (2)

The fourth bird
The fourth bird

Reputation: 163207

About the pattern you tried:

  • This part of the pattern (.*)(?=\|) Matches until the end of the line and then backtracks until it can assert a | to the right, which can match too much if there are multiple occurrences of | following.

  • This part of the pattern |(?<=cp1=).*(?<!a)$ is the second alternative, which also matches until the end of the line and asserts that it does not end with an a char, which seems out of place as you want to match /en-gb/ ending on /

You don't need any lookarounds to get /en-gb/, you can use a capture group as you are already using in your pattern.

Use a negated character class [^|]* to match any character except | to not cross matching the next one.

\bcp1=([^|]*)

Regex demo

const myString = "firstName=John|lastName=Smith|cp1=/en-gb/|age=30"
let currentCP1Value = myString.match(/\bcp1=([^|]*)/);
if (currentCP1Value) {
  console.log(currentCP1Value[1]);
}

Upvotes: 2

Why use regex at all? If your data doesn't contain text that can be interpreted as URL encoded segments, you can simply replace | with & and now you have a standard query string that JS has built-in parsing for through URLSearchParams:

const parsed = new URLSearchParams(input.replaceAll(`|`, `&`));
const cp = parsed.get(`cp1`);
// and many utility functions to perform further work

and you're done.

Upvotes: 1

Related Questions