【问题标题】:Regex for URL/String - If protocol return falseURL/字符串的正则表达式 - 如果协议返回 false
【发布时间】:2019-09-27 23:08:22
【问题描述】:

尝试创建一个字符串不应以 http(s)://、http(s)://www 开头的正则表达式。字符串的其余部分可以是任何东西。

我使用了这个正则表达式,但如果我们有 http://,它会返回 true

^(http://www.|https://www.|http://|https://)?[a-z0-9]+([-.]{1}[a-z0-9]+)*.[a-z]{2,5}(:[0-9]{1,5})?(/.*)?$

我试过的另一个是

var re = new RegExp("(http|https|ftp)://");
var str = "http://xxxx.com";
var match = re.test(str);
console.log(match);

这个也返回 true。

在这里演示

let re = /(http|https|ftp):///;
let url = 'xxxx.xxxx.xxxx'; // this is valid but test returns false
let url2 = 'https://www.xxzx.com/xxx.aspx'; // this should fail as there is https://www in url

console.log(re.test(url)); //
console.log(re.test(url2)); //

这可以用正则表达式吗?

【问题讨论】:

  • 你认为你的正则表达式应该如何丢弃你想要的字符串?在这种情况下,您需要使用负前瞻。

标签: javascript regex regex-lookarounds regex-group regex-greedy


【解决方案1】:

如果您只是想否定该正则表达式:

function doesMatch(string) {
	return !/^http(s):\/\/(?:www)?/.test(string);
}

[
	'https://www.xxzx.com/xxx.aspx',
	'http://www.xxxx.com',
	'https://xxxx.com',
	'http://xxxx.com',
	'https://aaaa.com',
	'aaaa.com'
].forEach(s => console.log(doesMatch(s)));

【讨论】:

    【解决方案2】:

    In your example code,re.test(url) 返回 false ,因为该字符串中不存在 http 或 https。 在 url2 (ie..'https://www.xxzx.com/xxx.aspx') 中,存在 https,所以它返回 true。

    【讨论】:

      【解决方案3】:

      您需要在正则表达式中使用负前瞻来丢弃以httphttpsftp 等协议开头的字符串。你可以使用这个正则表达式,

      ^(?!(?:ftp|https?):\/\/(www\.)?).+$
      

      Regex Demo

      JS 演示,

      const arr = ['xxxx.xxxx.xxxx','ftp://www.xxzx.com/xxx.aspx','https://www.xxzx.com/xxx.aspx','http://xxxx.com','https://xxzx.com/xxx.aspx','http://www.xxxx.com']
      
      arr.forEach(s => console.log(s + " --> " + /^(?!(?:ftp|https?):\/\/(www\.)?).+$/.test(s)))

      【讨论】:

      • 我们也可以让www.xxxx.com返回false吗?如果它以www. 开头失败。我做了一些改变,它奏效了。这是正确的方法吗regex101.com/r/ACBgQ9/2
      • 您的方法会拒绝以www 开头的字符串,但可以进行一些改进。让我看看并更新。
      • @phantomCoder:您需要使用的精确正则表达式是 ^(?!(?:(?:ftp|https?):\/\/|www\.)).+$
      【解决方案4】:

      这可能与正则表达式有关,但除非您必须使用正则表达式,否则您应该使用URL class

      let HTTP_URL = 'https://www.xxzx.com/xxx.aspx'
      let HTTPS_URL = 'https://www.xxzx.com/xxx.aspx'
      let FTP_URL = 'ftp://www.xxzx.com/xxx.aspx'
      let GOOD_PROTOCOL = 'mysql://www.xxzx.com/xxx.aspx'
      let GOOD_INPUT = '129.123.12.123'
      
      function test_url(url) {
          let bad_protocols = ['http:', 'https:', 'ftp:']
        try {
              var parsed = new URL(url)
        } catch {
          return true
        }
        return (!bad_protocols.contains(parsed.protocol))
      }
      
      test_url(HTTP_URL) //false
      test_url(HTTPS_URL) //false
      test_url(FTP_URL) //false
      test_url(GOOD_PROTOCOL) //true
      test_url(GOOD_INPUT) //true
      

      【讨论】:

      • 谢谢你,但如果可能的话,我正在寻找一个正则表达式,因为我使用的是 Yup()
      • @phantomCoder 你可以使用 .test() 验证器 (medium.com/@arkadyt/…)
      • 感谢您的链接,我更喜欢正则表达式解决方案,因为 URL 类在 IE 中存在问题。 +1
      【解决方案5】:

      这个表达式也可以工作,它会允许你想要的输入并且失败所有其他的 URL,你也可以简单地添加到它的字符列表中,还有什么可能不希望开始:

      ^([^http|s|ftp|www|\/\/|])*
      

      通过

      xxxx.xxxx.xxxx
      

      失败

      ftp://www.xxzx.com/xxx.aspx
      https://www.xxzx.com/xxx.aspx
      http://xxxx.com
      https://xxzx.com/xxx.aspx
      http://www.xxxx.com
      //www.xxxx.com
      

      您可以在this link 中测试/修改/更改它。

      正则表达式描述图

      此图表显示了表达式的工作原理,您可以在此 link 中可视化其他表达式:

      性能测试

      这个 JavaScript sn-p 使用简单的 100 万次 for 循环显示了该表达式的性能。

      const repeat = 1000000;
      const start = Date.now();
      
      for (var i = repeat; i >= 0; i--) {
      	const string = 'xxxx.xxxx.xxxx';
      	const regex = /(^([^http|s|ftp|www|\/\/|])*)/gm;
      	var match = string.replace(regex, "$1");
      }
      
      const end = Date.now() - start;
      console.log("YAAAY! \"" + match + "\" is a match ??? ");
      console.log(end / 1000 + " is the runtime of " + repeat + " times benchmark test. ? ");

      【讨论】:

        猜你喜欢
        • 2017-06-03
        • 2013-08-05
        • 1970-01-01
        • 2012-02-19
        • 2018-07-23
        • 1970-01-01
        • 2013-11-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多