2

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

6
  • Can you just count the number of &'s in the string and if it is more than 1 then you can assume there are more than 2 parameters? You could skip the regex altogether then. Commented May 23, 2016 at 20:55
  • I need to use regex since it is the only rule that I can apply to filter through the data element developer.android.com/guide/topics/manifest/data-element.html Commented May 23, 2016 at 21:08
  • Can't do something like if (StringUtils.countOccurrencesOf(url, "&") > 1) ? Commented May 23, 2016 at 21:10
  • @blahfunk thanks for taking the time to answer, but my regex is going to be added on an XML file, so I can't use code. Specifically inside the AndroidManifest.xml on the data element in the android:pathPattern="string" attribute Commented May 23, 2016 at 21:13
  • 1
    No worries! thanks! @blahfunk Commented May 23, 2016 at 21:17

3 Answers 3

2

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=).*$
Sign up to request clarification or add additional context in comments.

Comments

0

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.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.