【问题标题】:Validate URL query string with regex使用正则表达式验证 URL 查询字符串
【发布时间】:2014-07-20 11:51:43
【问题描述】:

我正在尝试使用正则表达式验证查询字符串。请注意,我不是要匹配这些值,而是验证它的语法。我这样做是为了练习正则表达式,所以我会感谢帮助而不是“使用这个库”,尽管看看它是如何在一个库中完成的会对我有所帮助,所以如果你有一个,请告诉我。

所以,这将是先决条件:

  • 必须以问号开头。
  • 它可能包含带或不带值的键,由等号分隔,对由 & 号分隔。

我已经走得很远了,但是我在匹配正则表达式时遇到了麻烦,即等号和 & 符号必须按特定顺序排列,而不必重复匹配组。这是我到目前为止所得到的:

#^\?([\w\-]+((&|=)([\w\-]+)*)*)?$#

它正确匹配?abc=123&def=345,但也错误匹配例如​​?abc=123=456

我可能会矫枉过正,做一些类似...

/^\?([\w\-]+=?([\w\-]+)?(&[\w\-]+(=?[\w\-]*)?)*)?$/

...但我不想重复相同的匹配组。

我如何告诉正则表达式,值之间的分隔符必须在 &= 之间迭代,而不重复匹配组或灾难性的回溯?

谢谢。

编辑:

我想澄清一下,这并不适用于现实世界的实现;为此,应使用您的语言中最有可能可用的内置库。问这个问题是因为我想提高我的正则表达式技能,而解析查询字符串似乎是一个有益的挑战。

【问题讨论】:

  • 这个问题在谷歌的“查询字符串正则表达式”搜索中弹出。我必须注意,即使您仅限于基于正则表达式的解决方案,这里发生的事情不应实时使用,因为它缺少this 点并且谁知道还有什么(我不知道,但那里有很多我不知道的规格)。

标签: regex validation expression


【解决方案1】:
/^\?([\w-]+(=[\w.\-:%+]*)?(&[\w-]+(=[\w.\-:%+]*)?)*)?$/

\w = [a-zA-Z0-9_]

? = '?'

以上正则表达式支持,a-z A-Z 0-9 _ . - : % + in Param Value

you can test this regex here

【讨论】:

    【解决方案2】:

    当你需要验证一个非常复杂的url时,你可以使用这个正则表达式

    `^(https|ftp|http|ftps):\/\/([a-z\d_]+\.)?(([a-zA-Z\d_]+)(\.[a-zA-Z]{2,6}))(\/[a-zA-Z\d_\%\-=\+]+)*(\?)?([a-zA-Z\d=_\+\%\-&\{\}\:]+)?`
    

    【讨论】:

      【解决方案3】:

      这是我做的。

      function isValidURL(url) {
        // based off https://mathiasbynens.be/demo/url-regex. testing https://regex101.com/r/pyrDTK/2
        var pattern = /^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:\/?)(?:(?:\?(?:(?!&|\?)(?:\S))+=(?:(?!&|\?)(?:\S))+)(?:&(?:(?!&|\?)(?:\S))+=(?:(?!&|\?)(?:\S))+)*)?$/iuS;
        return pattern.test(url);
      }
      

      基地:https://mathiasbynens.be/demo/url-regex

      测试:https://regex101.com/r/pyrDTK/4/

      【讨论】:

        【解决方案4】:

        这似乎是你想要的:

        ^\?([\w-]+(=[\w-]*)?(&[\w-]+(=[\w-]*)?)*)?$
        

        live demo

        这将每个“对”视为一个键,后跟一个可选值(可能为空白),并且有第一对,然后是可选的&,然后是另一对,以及整个表达式(除了前导@ 987654324@) 是可选的。这样做会阻止匹配?&abc=def

        另请注意,连字符在字符类中的最后一个时不需要转义,允许稍微简化。

        您似乎希望在键或值中的任何位置都允许使用连字符。如果键需要不含连字符:

        ^\?(\w+(=[\w-]*)?(&\w+(=[\w-]*)?)*)?$
        

        【讨论】:

        • 谢谢,这就是我正在使用的。不过,我一直在寻找一种不重复匹配组的方法。
        • 不幸的是没有办法。能够标记一个块并重用它会很好,但不是。
        • 谢谢,这就是我要找的答案 =)
        • 虽然完全有效,但不匹配:"?q=denbosch&lat=45.234342364&long=-45.234342364"
        • @BartBurg 在字符类中添加一个点:^\?(\w+(=[\w.-]*)?(&\w+(=[\w.-]*)?)*)?$
        【解决方案5】:

        你可以使用这个正则表达式:

        ^\?([^=]+=[^=]+&)+[^=]+(=[^=]+)?$
        

        它的作用是:

        NODE                     EXPLANATION
        --------------------------------------------------------------------------------
          ^                        the beginning of the string
        --------------------------------------------------------------------------------
          \?                       '?'
        --------------------------------------------------------------------------------
          (                        group and capture to \1 (1 or more times
                                   (matching the most amount possible)):
        --------------------------------------------------------------------------------
            [^=]+                    any character except: '=' (1 or more
                                     times (matching the most amount
                                     possible))
        --------------------------------------------------------------------------------
            =                        '='
        --------------------------------------------------------------------------------
            [^=]+                    any character except: '=' (1 or more
                                     times (matching the most amount
                                     possible))
        --------------------------------------------------------------------------------
            &                        '&'
        --------------------------------------------------------------------------------
          )+                       end of \1 (NOTE: because you are using a
                                   quantifier on this capture, only the LAST
                                   repetition of the captured pattern will be
                                   stored in \1)
        --------------------------------------------------------------------------------
          [^=]+                    any character except: '=' (1 or more times
                                   (matching the most amount possible))
        --------------------------------------------------------------------------------
          (                        group and capture to \2 (optional
                                   (matching the most amount possible)):
        --------------------------------------------------------------------------------
            =                        '='
        --------------------------------------------------------------------------------
            [^=]+                    any character except: '=' (1 or more
                                     times (matching the most amount
                                     possible))
        --------------------------------------------------------------------------------
          )?                       end of \2 (NOTE: because you are using a
                                   quantifier on this capture, only the LAST
                                   repetition of the captured pattern will be
                                   stored in \2)
        --------------------------------------------------------------------------------
          $                        before an optional \n, and the end of the
                                   string
        

        【讨论】:

        • 这匹配"? = "
        • @Amit Joki 你从哪里得到的打印输出?
        【解决方案6】:

        我同意 Andy Lester 的观点,但可能的正则表达式解决方案是

        #^\?([\w-]+=[\w-]*(&[\w-]+=[\w-]*))?$#
        

        这与您发布的内容非常相似。

        我没有测试它,你也没有说你使用的是什么语言,所以它可能需要一些调整。

        【讨论】:

        • 是的,这是为了练习 =) 谢谢你的回答,这几乎是我现在正在使用的,但它仍然重复匹配组,这是我想避免的。跨度>
        • @HelgeTalvikSöderström 为什么?这根本不可能。
        【解决方案7】:

        这可能不是正则表达式的工作,而是你选择的语言中的现有工具。正则表达式不是你对碰巧涉及字符串的每个问题挥舞的魔杖。您可能希望使用已经编写、测试和调试过的现有代码。

        在 PHP 中,使用 parse_url 函数。

        Perl:URI module.

        鲁比:URI module.

        .NET:'Uri' class

        【讨论】:

        • 感谢您的回复,但如果您再次阅读我的帖子,您会看到I'm doing this to practice regex, so I'd appreciate help rather than "use this lib"
        • 是的,我看到了,而且我也知道人们无论如何都会找到这个答案。我在考虑未来的用户以及您。
        • 好吧,我将其解释为为可能正在寻找另一个答复的人提供答案,偶然发现这个问题......如果我们继续讨论正则表达式,而不是特定的,我将不胜感激我用于练习的示例。
        • parse_url() 几乎会尝试解析任何内容...您不能将其用作验证。它甚至返回JSON 字符串的结果:)
        猜你喜欢
        • 2023-03-03
        • 1970-01-01
        • 2021-03-16
        • 1970-01-01
        • 1970-01-01
        • 2018-10-10
        • 1970-01-01
        相关资源
        最近更新 更多