Julian Suarez
Julian Suarez

Reputation: 4521

How to test if a URL contains certain parameters but not others using regex

I have an url in this format:

http://www.example.com/path?param1=value1&param2=value2

I need a regex to match the path and params1 and params2 in any order but if param3 is present then I need it to fail so:

String str1 = "/path?param1=value1&param2=value2"; // This will match
String str2 = "/path?param2=value2&param1=value1"; // This will match
String str3 = "/path?param1=value1&param2=value&param3=value3"; // This will not match

So for I've tried using lookarounds to match the parameters but it is failing:

/path\?(?!param3)(?=param1=.*)(?=param2=.*)

Any thoughts?

P.D. For the curious I'm trying to match a specific URL from an AndroidManifest.xml file https://developer.android.com/guide/topics/manifest/data-element.html

Upvotes: 2

Views: 2726

Answers (3)

ABJ
ABJ

Reputation: 309

The regex provided by Michael works well but there is a glitch. It also evaluates newParam. So we should change that with:

^(?!.*(\\?|&)param3)(?=.*(\\?|&)param1=)(?=.*(\\?|&)param2=).*$

Basically we check if the parameter name starts with a ? or &. Also if you want to make a parameter optional then you can just put a ? at the end like:

(?!.*(\\?|&)param3)(?=.*(\\?|&)param1=)(?=.*(\\?|&)param2=)?.*$

In the above param2 is optional.

Upvotes: 0

zgc7009
zgc7009

Reputation: 3389

This started as a comment and I got a little carried away. You can sanitize the query and see if it matches the parameters you need it to and avoid regex all together (if possible)

private boolean checkProperQueryString(String url, String[] requiredKeys){
    try{
        UrlQuerySanitizer sanitizer = new UrlQuerySanitizer(url);

        // Check that you have the right number of parameters
        List<UrlQuerySanitizer.ParameterValuePair> parameters =
               sanitizer.getParameterList();
        if(parameters == null || parameters.size() != requiredKeys.length)
            return false;

        // Check to make sure that the parameters you have are the
        // correct ones
        for(String key : requiredKeys){
            if(TextUtils.isEmpty(sanitizer(getValue(key))
                return false;
        }

        // We pass every test, success!
        return true;   
    } catch(Exception e){
        // Catch any errors (haven't tested this so not sure of errors)
        e.printStackTrace();
        return false;
    }
}

You can then make the call doing something like this

boolean validUrl = checkProperQueryString(url, new String[]{"param1", "param2"});

This doesn't directly answer your question, again just too much for a comment :P

Let me know if this just adds confusion for anyone and I can remove it.

Upvotes: 0

Michael Markidis
Michael Markidis

Reputation: 4191

Try this one out:

^(?!.*param3)(?=.*param1=)(?=.*param2=).*$

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

If you want the path in as well, then

^\/path(?!.*param3)(?=.*param1=)(?=.*param2=).*$

Upvotes: 2

Related Questions