2

I have this two strings:

(username~contains~'ren'~and~status~contains~false)
(status~contains~false~and~username~contains~'ren')

i need one regex that find what is the status value after contains~

I try something like:

/(?<=status~contains~).*?(?=[)])|(?<=status~contains~).*?(?=~)/gi

pass in exemple 1: (username~contains~'ren'~and~status~contains~false)
fail in exemple 2: (status~contains~false~and~username~contains~'ren')

I need only the return true or false, but in the second exemple i get false~and~username~contains~'ren'

4 Answers 4

1

The thing that you could change is to match either a ~ or )

(?<=status~contains~).*?(?=[)~])

Regex demo

Instead of using a lookbehind (which is not yet fully supported across browsers), you could also use a capturing group instead and make sure there are opening and closing parenthesis.

The value is in group 1.

\((?:[^~\r\n]+~)*status~contains~([^~\n]+)(?=[^()]*\)) 
  • \( Match an opening (
  • (?: Non capturing group
    • [^~\r\n]+~ Match 1+ times any char except ~ or a newline
  • )* Close goup, repeat 0+ times
  • status~contains~ Match literally
  • ( Capture group 1
    • [^~\n]+ Match 1+ times any char except ~ or a newline
  • ) Close group
  • (?=[^()]*\)) Positive lookahead, assert a closing )

Regex demo

const regex = /\((?:[^~\r\n]+~)*status~contains~([^~\n]+)(?=[^()]*\))/g;
const str = `(username~contains~'ren'~and~status~contains~false)
(status~contains~false~and~username~contains~'ren')`;
let m;

while ((m = regex.exec(str)) !== null) {
  // This is necessary to avoid infinite loops with zero-width matches
  if (m.index === regex.lastIndex) {
    regex.lastIndex++;
  }
  console.log(m[1]);
}

Sign up to request clarification or add additional context in comments.

3 Comments

the first example looks good, but the second without lookbehind don't pass, test it in reg site
@Jhonny In the second example the value is in the first capturing group. This is an example with a different engine selected which will highlight the groups in green. regex101.com/r/YNLdOO/1 You can get those matches using the example Javascript and it does not use lookarounds.
ooh, thanks for the explication. i will accept your answer because is the most explained
1

Try this regex:

/(?<=status~contains)~([^~)]+)[~)]/

and get group 1 from result.

Comments

1

True or false /^(?=.*status~contains~(true|false)).*/
Use the multi-line option and group 1 is the value.

https://regex101.com/r/N41U56/1

Comments

1
/(?<=status~contains~)[^~)]+(?=[~)])/g

This uses a lookbehind of: status~contains~ and a lookahead of either ~ or ). Therefore we can match 1 or more characters that are neither ~ nor ) between the lookbehind and lookahead. This is simpler and more efficient than using .*?.

let re = /(?<=status~contains~)[^~)]+(?=[~)])/g;
let text = "(username~contains~'ren'~and~status~contains~false)" +
           "(status~contains~false~and~username~contains~'ren')";
let m;
while (m = re.exec(text))
    console.log(m[0]);

See Regex Demo

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.