【问题标题】:How to test if a URL contains certain parameters but not others using regex如何使用正则表达式测试 URL 是否包含某些参数但不包含其他参数
【发布时间】:2016-09-20 21:18:15
【问题描述】:

我有一个这种格式的网址:

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

我需要一个正则表达式以任何顺序匹配路径和 params1 和 params2,但如果 param3 存在,那么我需要它失败:

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

所以我尝试使用环视来匹配参数,但它失败了:

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

有什么想法吗?

P.D.出于好奇,我正在尝试匹配 AndroidManifest.xml 文件中的特定 URL https://developer.android.com/guide/topics/manifest/data-element.html

【问题讨论】:

  • 你能数出字符串中 & 的数量,如果它超过 1,那么你可以假设有超过 2 个参数吗?你可以完全跳过正则表达式。
  • 我需要使用正则表达式,因为这是我可以应用的唯一规则来过滤数据元素developer.android.com/guide/topics/manifest/data-element.html
  • 不能像if (StringUtils.countOccurrencesOf(url, "&") > 1) 那样做?
  • @blahfunk 感谢您花时间回答,但我的正则表达式将被添加到 XML 文件中,所以我不能使用代码。特别是在 AndroidManifest.xml 中数据元素中的 android:pathPattern="string" 属性
  • 别担心!谢谢! @blahfunk

标签: java android regex


【解决方案1】:

Michael 提供的正则表达式运行良好,但有一个小故障。它还评估 newParam。所以我们应该改变它:

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

基本上我们检查参数名称是否以?要么 &。此外,如果您想让参数成为可选参数,那么您可以只放一个 ?最后像:

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

在上面的 param2 是可选的。

【讨论】:

    【解决方案2】:

    这开始是一个评论,我有点得意忘形。您可以清理查询并查看它是否与您需要的参数匹配并避免一起使用正则表达式(如果可能)

    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;
        }
    }
    

    然后你就可以像这样拨打电话

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

    这并不能直接回答您的问题,再次评论太多了:P

    如果这只会增加任何人的困惑,请告诉我,我可以将其删除。

    【讨论】:

      【解决方案3】:

      试试这个:

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

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

      如果你也想要路径,那么

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-02-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-05
        • 1970-01-01
        • 2021-12-24
        • 1970-01-01
        相关资源
        最近更新 更多