Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript regular expression question mark after parentheses

I want to capture some string only if it's appear so i use ? after capture () meaning i want to capture that part of that string but it does not have to be shown (zero or one) but when i add ? after () it drop that match:

var str = 'blablablacaptureblablabla';

if i make a regular capture with () i get the desire capture:

console.log(str.match(/.*(capture).*/i)); // array[1] = capture

if i add ? to indicate capture may be or not be at all i get undefined:

console.log(str.match(/.*(capture)?.*/i)); // array[1] = undefined

why is that ? all i want is the capture the word capture whether its present or not in the string so this will not return null:

var str = 'blablablalablabla'; //string without word 'capture'
console.log(str.match(/.*(capture)?.*/i)); // this will work but if i use it with string with the word 'capture' it won't capture the 'capture'

EDIT:

Just to be clear - I want this string blablacaptureblabla to capture the word capture and also this string blablablabla to not return null cause i use ? which means zero or one

like image 408
Adidi Avatar asked Apr 17 '26 09:04

Adidi


1 Answers

If you want the capture value to be always initialized (to avoid undefined value for Capturing group #1) you need to use an obligatory group with an empty alternation and use the tempered greedy token (?:(?!capture).)*:

/^(?:(?!capture).)*(capture|).*/i

See regex demo

A tempered greedy token is a special construct made of a (non-)capturing group ((?:...) or (...)) matching a single character that is not starting a specific sequence (that is specified with a negative lookahead, (?!...)), to which a quantifier is applied.

Below is a JS demo:

var str = 'blablablalablabla'; //string without word 'capture'
document.body.innerHTML = '"' + str.match(/^(?:(?!capture).)*(capture)?.*/i)[1] + '"<br/>'; // undefined, as the group is optional
document.body.innerHTML += '"' + str.match(/^(?:(?!capture).)*(capture|).*/i)[1] + '"<br/>'; //  empty string, the group is obligatory
var str1 = 'blablabcapturelalablabla';
document.body.innerHTML += '"' + str1.match(/^(?:(?!capture).)*(capture|).*/i)[1] + '"';
like image 100
Wiktor Stribiżew Avatar answered Apr 19 '26 21:04

Wiktor Stribiżew