MedicineMan
MedicineMan

Reputation: 15314

How do I match string patterns except for one version

I have a set of strings that we want to surface to the users.

We want to match all strings which take the form XYZ-____-xxx-tests except when ____ is API.

ABCDEFGH - don't match
XYZ-api-xxx-tests - don't match
XYZ-google-xxx-tests - match
XYZ-bing-xxx-tests - match

We are using a regex right now, but it matches even the "API" version of the string pattern. How do I change my regex so it doesn't match?

Upvotes: 0

Views: 68

Answers (3)

Adam Smith
Adam Smith

Reputation: 54183

Depending on how you use the results, another commonly-used idiom is to put the blacklisted "match" in the first alternation, then capture the second alternation.

XYZ-api-xxx-tests|(XYZ-\w+-xxx-tests)

This should match regardless, but if the compared string is the blacklisted match, it won't have anything in the captured group. You'll end up with a bunch of results that are either a string or nothing, and can filter from there.

Upvotes: 1

Duc Filan
Duc Filan

Reputation: 7157

This is the one that works:

XYZ-(?!api).*-xxx-tests

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

Negative Lookahead (?!api)

  • Assert that the Regex below does not match api matches the characters api literally (case sensitive)

const regex = /XYZ-(?!api).*-xxx-tests/g;
const str = `ABCDEFGH - don't match
XYZ-api-xxx-tests - don't match
XYZ-google-xxx-tests - match
XYZ-bing-xxx-tests - match
`;
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++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

Upvotes: 0

TheChetan
TheChetan

Reputation: 4596

Try: XYZ-(?!api)\w+-xxx-tests

(?!api) is a negative lookahead for the word api. So after XYZ-, if it finds an api, it will stop matching. \w+ for any alphanumeric characters in the same place. The rest of the string is just actual character matching.

See for regex demo and explanation: https://regex101.com/r/Pc7lBP/1

Upvotes: 1

Related Questions