DEV Community

Cover image for Regex - underrated or overHATED? Part 3/3
Vinicius Cerqueira Bonifácio
Vinicius Cerqueira Bonifácio

Posted on

Regex - underrated or overHATED? Part 3/3

Hi again, dearest devs on earth. 🌎 🌍 🌏

I am back in business, bringing the last part of our Regex series.

Jim Carrey

Thanks a lot for been following and interacting with the article so far. :) It is really a great pleasure having you all here. 🙇‍♂️

If you are puzzled, please check out the parts 1/3 and 2/3 so this last one may make more sense. (or not 🤷‍♂️)

I am going to cover few more topics and after that I am sure you are good to go and apply your knowledge by yourself. At least it has been my aim since the beginning. 🎯

Take you mug filled with coffee and let's cut to the chase. ☕

Lookahead (Positive and Negative)

The name kind of describe what it does. Now, we only need to know how to "write" it and where to use it. Don't panic! I am here.

Calm down - CR7

  • Positive Lookahead (?= ) 👍

The positive lookahead operator returns an array if the pattern was found or null instead.

Just to be more concise, when using along with the .match() method, the result will be either [ '', index: 0, input: '<the pattern here>', groups: undefined ] or null.

When working with lookaheads I particularly prefer using .test() than match() because, in the end, we are expecting an answer either "yes" or "not". (true or false)

I know, more gibberish so let's use an example here.

Imagine you have built a login form in your website and you want all the passwords to fulfill a given criteria before accept storing them. Let's say, it must:

  • have a minimum of 10 characters,
  • have up to 15 characters, (🙏 always use more if possible 💡)
  • should include one or more numbers on it.

Of course we could do that validation using plain JavaScript but, trust me, it would be as painful as stubbing your little toe on a corner. 😹 💦

Stubbing Toe

This is why using lookahead comes to our rescue.

// Not good at all tbh 
let goodPassword = "neverput1234" 
Enter fullscreen mode Exit fullscreen mode

Our lookahead Regex:

 let ourRegex = /(?=\w{10,15})(?=\D*\d)/
Enter fullscreen mode Exit fullscreen mode

Express explanation: ⏩

  • (?=\w{10,15}): it will search for alphanumeric characters in a range between 10 and 15.
  • (?=\D*\d): it will search for zero or more non-numeric characters (\D*) followed by a number (/d).

In order to return a pattern of characters, it must fulfill both requirements above. Think it as the && (and) logical operator.

Boilerplate same from previous parts:

let hasPattern = ourRegex.test(goodPassword);
let patternMatched = goodPassword.match(ourRegex);

console.group('The Result of our comparison');
console.log('Has Pattern?:', hasPattern);
console.log('The Pattern: ', patternMatched);
console.groupEnd();
Enter fullscreen mode Exit fullscreen mode

Should log on console:

The Result of our comparison
  Has Pattern?: true
  The Pattern:  [ '', index: 12, input: 'neverput1234', groups: undefined ]
Enter fullscreen mode Exit fullscreen mode
  • Negative Lookahead (?! ) 👎

I am sure you already figured out how it works. It is like making the same question but in "negative" way. (⚠️ lack of grammatical jargon detected! 😬)

We have this sample string:

let status = 'people happy people happy people happy';
Enter fullscreen mode Exit fullscreen mode

Your question would be like:
" - Do we have at least one person not happy there?"
💡 I didn't write unhappy because it would be any thing other than happy, for instance, bored. 😅

let ourRegex = /people(?!\shappy)/;

let hasPattern = ourRegex.test(status);
let patternMatched = status.match(ourRegex);

console.group('The Result of our comparison');
console.log('Has Pattern?:', hasPattern);
console.log('The Pattern: ', patternMatched);
console.groupEnd();
Enter fullscreen mode Exit fullscreen mode

The Regex's answer (🤖) would be: "- There is no people other than happy there. (false)"

The Result of our comparison
  Has Pattern?: false
  The Pattern:  null
Enter fullscreen mode Exit fullscreen mode

I hope you have got the point. It is a little tricky indeed. 🧠 💥

Capturing Groups ()

We can also use parenthesis to capture patterns found in a given group, for example:

  • In a mixed grouping of chars:
let alleatorySentence = 'Publishment is not a punishment.';
let ourRegex = /P(ublis|unis)hment/gi;

let hasPattern = ourRegex.test(alleatorySentence);
let patternMatched = alleatorySentence.match(ourRegex);
Enter fullscreen mode Exit fullscreen mode

Brings us the following:

The Result of our comparison
  Has Pattern?: true
  The Pattern:  [ 'Publishment', 'punishment' ]
Enter fullscreen mode Exit fullscreen mode

Reusing patterns:

let isnow = 'Snow Snow Snow';
let ourRegex = /((\w+)\s)/g; 
Enter fullscreen mode Exit fullscreen mode

In the console:
(Remember to use the provided console.log() boilerplate above)

The Result of our comparison
  Has Pattern?: true
  The Pattern:  [ 'Snow ', 'Snow ' ]
Enter fullscreen mode Exit fullscreen mode

☝️ The last Snow in the original string is not followed by a empty space \s so it was not included in the results.

Search and Replace

This is very interesting. Everybody knows what the replace() method does ...

let activity = "I like sleeping a lot"
let beHealthy = activity.replace(/sleeping/, "surfing and coding")
Enter fullscreen mode Exit fullscreen mode

The beHealthy variable now holds the I like surfing and coding a lot value. 🥰

But how about switching places?

let poorPhrase = 'I and you went to a bootcamp last year.';
let switchRegex = /(\w+)\s(\w+)\s(\w+)/
let slightlyBetter = poorPhrase.replace(switchRegex, '$3 $2 $1')
Enter fullscreen mode Exit fullscreen mode

What have just happened?

In short, our regex have matched those values inside of the parenthesis:

  • I as $1,
  • and as $2,
  • you as $3.

And in that sentence $3 $2 $1 we have switched their places in the string. Cool, isn't it? 😝

🤫 Just pretend you didn't see the lowercase you in the beginning of the phrase. 🤫

And that is it, guys. We have reached the end of the regex series.

Leonardo Dicaprio clapping hands

I don't remember anything else to add here. Maybe the trim() method but to be honest, it doesn't need any deep explanation.

I would like to thank you all for sticking with me until here and I hope I can bring you more interesting stuff very soon.

Take care everybody and Toodle Pip! 🖖

Top comments (0)