daily
daily

Reputation: 11

Combine two JavaScript regular expressions into one

Background:

I'm using director.js to match routes, and using regex for different parameters.

Problem:

Need to come up with a regex for a parameter which matches regex 1 while not matching regex 2 (I know it's bad design but there're various reasons which I have to do it this way)

  1. [._a-zA-Z0-9-%!\(\)'*]+
  2. [a-z0-9][a-zA-Z0-9]{3}(0[a-zA-Z0-9]{2}|[a-zA-Z0-9]00)[a-zA-Z0-9]{8}([a-zA-Z0-9]{3})?

What's the best way of doing this?

Update:

Thanks to gyre. I think something similiar to (?![a-z0-9][a-zA-Z0-9]{3}(0[a-zA-Z0-9]{2}|[a-zA-Z0-9]00)[a-zA-Z0-9]{8}([a-zA-Z0-9]{3})?)(?:[._a-zA-Z0-9-%!()'*]+) is what I want, but it doesn't work when I tried in my application, using this regex in https://regex101.com/, it can still find a match for string "00Bxx0000025e1UEA" --> Bxx0000025e1UEA which I think the library was confused somehow. Is there anyway to update the regex to not find a match for "00Bxx0000025e1UEA" at all?

I have tried to add ^ and $ for the regex: (?!^[a-z0-9][a-zA-Z0-9]{3}(0[a-zA-Z0-9]{2}|[a-zA-Z0-9]00)[a-zA-Z0-9]{8}([a-zA-Z0-9]{3})?$)(?:[._a-zA-Z0-9-%!()'*]+) but that's still incorrect.

Upvotes: 0

Views: 4197

Answers (4)

trincot
trincot

Reputation: 350137

You could do it in one regular expression like this:

^(?![a-z0-9][a-zA-Z0-9]{3}(0[a-zA-Z0-9]{2}|[a-zA-Z0-9]00)[a-zA-Z0-9]{8}([a-zA-Z0-9]{3})?$)[._a-zA-Z0-9-%!()'*]+$

The part that you want to reject comes first between (?! ), which means it looks ahead and will fail the match if that part matches.

The additional ^ and $ will make sure the match is done at the start of the string up until the very end of that string.

The pattern that you do want to match is placed at the end, again with an additional $ to prevent that other characters follow the pattern.

See it on regex101.com

Depending on your expectations, you might want to remove the first $. Remove it, if you also want to fail strings that have the exclusion pattern with some other characters following it. If however such suffixed characters make the string potentially acceptable, you should keep that $.

Upvotes: 0

gyre
gyre

Reputation: 16779

You are essentially looking for this pattern, which uses a negative lookahead to ensure that the match for <first> is not also a match for <second>:

/(?! <second> )(?: <first> )/

var first = /[._a-zA-Z0-9-%!()'*]+/
var second = /[a-z0-9][a-zA-Z0-9]{3}(0[a-zA-Z0-9]{2}|[a-zA-Z0-9]00)[a-zA-Z0-9]{8}([a-zA-Z0-9]{3})?/

var third = new RegExp('(?!' + second.source + ')(?:' + first.source + ')')

console.log(third)

Upvotes: 2

Nitesh
Nitesh

Reputation: 1550

If you need to match regex1 and not match regex2 then why can't you check as,

var isTrue = regex1.test(str) && !regex2.test(str)

Upvotes: 0

mgul
mgul

Reputation: 742

Try this:

var str = "the string to test"
var re1 = "your first regex, [._a-zA-Z0-9-%!()'*]+"
var re2 = "your second regex, [a-z0-9][a-zA-Z0-9]{3}(0[a-zA-Z0-9]{2}|[a-zA-Z0-9]00)[a-zA-Z0-9]{8}([a-zA-Z0-9]{3})?"

if(str.search(re1) != -1 && str.search(r2) == -1) {
    // your action
}

search will return -1 if there is no match

Upvotes: 0

Related Questions