【问题标题】:JS Regex url validationJS 正则表达式 url 验证
【发布时间】:2015-09-07 07:42:35
【问题描述】:

我尝试使用或不使用 http 来验证 url,无论我做了什么,函数都返回 false。 我在这个网站上检查了我的正则表达式字符串: http://regexr.com/ 正如我所期望的那样。

    function isUrlValid(userInput) {
        var regexQuery = "/(http(s)?://.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/";
        var url = new RegExp(regexQuery,"g");
        if (url.test(userInput)) {
            alert('Great, you entered an E-Mail-address');
            return true;
        }
        return false;
    }

我通过将 .test 更改为 .match 并保留正则表达式来解决问题。

【问题讨论】:

    标签: javascript jquery regex web


    【解决方案1】:

    我将函数更改为 Match + 在此处使用斜杠及其工作进行更改:(http(s)?://.)

    固定函数:

    function isUrlValid(userInput) {
        var res = userInput.match(/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/g);
        if(res == null)
            return false;
        else
            return true;
    }
    

    【讨论】:

    • 应该是 (http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&=]*) 。在regex101.com 上检查上述正则表达式会出错。
    【解决方案2】:

    我相信其他答案会拒绝一些有效的网址(如大写的域名或长子域)并允许一些无效的网址(如http://www.-example-.com 或 www.%@&.com)。我尝试考虑一些额外的 url 语法规则(不涉及国际化)。

    function isUrlValid(userInput) {
        var regexQuery = "^(https?://)?(www\\.)?([-a-z0-9]{1,63}\\.)*?[a-z0-9][-a-z0-9]{0,61}[a-z0-9]\\.[a-z]{2,6}(/[-\\w@\\+\\.~#\\?&/=%]*)?$";
        var url = new RegExp(regexQuery,"i");
        return url.test(userInput);
    }
    var input = ["https://o.sub-domain.example.com/foo/bar?foo=bar&boo=far#a%20b",
                 "HTTP://EX-AMPLE.COM",
                 "example.c",
                 "example-.com"];
    for (var i in input) document.write(isUrlValid(input[i]) + ": " + input[i] + "<br>");

    为了还允许 IP 地址和端口号,正则表达式为:

    "^(https?://)?(((www\\.)?([-a-z0-9]{1,63}\\.)*?[a-z0-9][-a-z‌​0-9]{0,61}[a-z0-9]\\‌​.[a-z]{2,6})|((\\d{1‌​,3}\\.){3}\\d{1,3}))‌​(:\\d{2,4})?(/[-\\w@‌​\\+\\.~#\\?&/=%]*)?$‌​"  
    

    为了也允许查询字符串在域名和问号之间没有斜线(理论上是不允许的,但在大多数实际情况下都可以),正则表达式是:

    "^(https?://)?(((www\\.)?([-a-z0-9]{1,63}\\.)*?[a-z0-9][-a-z‌​0-9]{0,61}[a-z0-9]\\‌​.[a‌​-z]{2,6})|((\\d‌​{1,3}\\.){3}\\d{1,3}‌​))(:\\d{2,4})?((/|\\‌​?)[-\\w@\\+\\.~#\\?&‌​/=%]*)?$"
    

    为了确保每个 % 后跟一个十六进制数字,正则表达式为:

    "^(https?://)?(((www\\.)?([-a-z0-9]{1,63}\\.)*?[a-z0-9][-a-z‌​0-9]{0,61}[a-z0-9]\\‌​.[a-z]{2,6})|((\\d{1‌​,3}\\.){3}\\d{1,3}))‌​(:\\d{2,4})?((/|\\?)‌​(((%[0-9a-f]{2})|[-\‌​\w@\\+\\.~#\\?&/=])*‌​))?$"
    

    (注:正如John Wu在评论中提到的,有有效的single-letter domains

    【讨论】:

      【解决方案3】:

      其实这个问题需要强大的regex,下面的代码也不是很难看懂,请看下面(ES6 - TypeScript):

      const isValidUrl = (url: string): boolean => {
        const urlRegex = /^((http(s?)?):\/\/)?([wW]{3}\.)?[a-zA-Z0-9\-.]+\.[a-zA-Z]{2,}(\.[a-zA-Z]{2,})?$/g;
        const result = url.match(urlRegex);
      
        return result !== null;
      };
      

      【讨论】:

        【解决方案4】:

        试试这个代码。

        function CheckURL(fieldId, alertMessage) {
            var url = fieldId.value;
            if(url !== "")
            {
                if (url.match(/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/g) !== null)
                    return true;
                else {
                    alert(alertMessage);
                    fieldId.focus();
                    return false;
                }
            }
        }
        
        var website = document.getElementById('Website');
        if (!CheckURL(website, "Enter a valid website address")) {
            return false;
        }
        

        【讨论】: