Regex - match set of words literally with special characters at the front and back of each word

Viewed 235

This is my regex matcher.

const regex = /\b(?:days|weeks|months)\b/gi

If I pass a string like

There are 5 $days/$ and ten %weeks/% and 7 $months/$

I want to return an array with all the matches for each word like

['months', 'days', 'weeks'] 

or

['$months/$', '$days/$', '%weeks/%']

However, this string should not return days since there is no delimiter $ or /$ or % or /%

There are 5 days and ten %weeks/% and 7 $months/$

would return


['months', 'weeks'] 

or

['$months/$', '%weeks/%']

Here is what I have tried without success (just for days for now)


/\b(?:\$days|weeks|months)\b/gi
/\b(?:\$days\/\$|weeks|months)\b/gi

What is the correct pattern to match these 3 specific words with these particular delimiters that I append to the end of them?

2 Answers

Your initial regex can be fixed like this:

/(?<=([$%]))(?:days|weeks|months)(?=\/\1)/g

See the regex demo. A capturing group version:

/(?:\/?\$|\/?%)(days|weeks|months)\b/g

See this demo. The point is that you used a word boundary before the dollar symbol before days and it made the pattern only match $days right after a letter, digit or underscore. By using a custom boundary, the lookbehind or a group, this is easily fixed.

If you need to find the values only if there is a special char at the front and the same char after / at the end, you may use

/(?<=([$%]))(?:days|weeks|months)(?=\/\1)/g
/([$%])(days|weeks|months)\/\1/g

See this regex demo and this one.

See a JavaScript demo:

const strings = ['There are 5 $days/$ and ten %weeks/% and 7 $months/$', 'There are 5 days and ten %weeks/% and 7 $months/$'];
for (const x of strings) {
  // Getting clean results with the lookaround-based pattern:
  console.log(x.match(/(?<=([$%]))(?:days|weeks|months)(?=\/\1)/g, x));
  // Getting whole matches and clean results:
  const results = [...x.matchAll(/([$%])(days|weeks|months)\/\1/g)];
  console.log(Array.from(results, m => [m[0], m[2]]));
}

What you need is a match method and RegExp object.

let sentense = 'There are 5 $days/$ and ten %weeks/% and 7 $months/$';
let regex = new RegExp('(month)|(week)|(days)','gmi');
 let filter = sentense.match(regex);
 console.log(filter)    //["days", "week", "month"]

Related