JavaScript正则表达式 - 域名URL

3
我有一个包含“URL”字段的表单。用户需要在文本框中填写第一部分。第二部分是预定义的,显示在文本框右侧。
例如,用户在文本框中输入“test”。第二部分被预定义为“.example.com”。所以总URL变为“test.example.com”。
我需要一个正则表达式来验证第一部分。必须满足以下条件:
1. 不得以连字符开头或结尾 2. 必须至少包含一个字母 3. 长度应在4到21之间
我使用了正则表达式/ ^(?!:\/\/)([a-zA-Z0-9] + \。)?[a-zA-Z0-9] [a-zA-Z0-9-] + \。[a-zA-Z] {2,6}?$ / I,该正则表达式在以下主题中提到: Javascript regex to match fully qualified domain name, without protocol, optional subdomain 但是这个正则表达式验证整个URL(包括第二部分),我只需要验证第一部分。如何修改当前的正则表达式以满足要求?

1
与其重新发明正则表达式,为什么不将第一部分作为单独的变量存储,验证该部分,然后再将其与第二部分连接起来呢? - freginold
我也是这么想的。有没有可以验证上述 3 个条件的正则表达式? - prajeesh
3个回答

1

分解它。使用正则表达式:

  • /^-|-$/(必须匹配)
  • /[a-z]/i(必须匹配)
  • /^[a-z0-9-]{4,21}$/i(必须匹配)

这样做的好处是可以向用户提供有意义的错误信息。

document.getElementById('subdomain').addEventListener("input",function() {
  var input = this.value;
  if( input.match(/^-|-$/)) this.setCustomValidity("Cannot start or end with a hyphen");
  else if( !input.match(/[a-z]/i)) this.setCustomValidity("Must contain at least one letter");
  else if( !input.match(/^[a-z0-9-]{4,21}$/)) this.setCustomValidity("Must be between 4 and 21 characters long");
  // add additional checks here, eg. /^[0-9]/ => Cannot start with a number
  else this.setCustomValidity("");
},true);
<form>
  <input type="text" id="subdomain" />.example.com
</form>


1
我点赞了,因为将正则表达式分解为单个子句更具建设性和组织性。 - Thielicious
我进行了点赞,因为回答中有很多无用的垃圾,例如未经请求的表单和浏览器元素;此外,OP声明希望只接收一个正则表达式,而这个答案显然与作者的意图相冲突。实际上,从一个拥有234k的人,看到这样的答案真是奇怪。 - smnbbrv
@smnbbrv MVCE需要表单,因为没有表单就无法进行验证。其次,你听说过X/Y问题吗?有时候,当用户要求Y时,为X提供解决方案可能更好。这就是为什么我,一个“拥有234k的人”,拥有234k。只是这么说一下... - Niet the Dark Absol

0

这应该能解决问题:

/^(?=.*[A-Za-z])([0-9A-Za-z][0-9A-Za-z-]{2,19}[0-9A-Za-z])$/

解释:

  • (?=.*[A-z]) 正向前瞻(至少一个字符来自集合 [A-z]
  • ([0-9A-z] 不带连字符的模式开头
  • [0-9A-z]) 不带连字符的模式结尾
  • [0-9A-z-]{2,19} - 第一个和最后一个字符之间应该包含的其余字符(带连字符,从 4 - 221 - 2

检查:

var RE = /^(?=.*[A-z])([0-9A-z][0-9A-z-]{2,19}[0-9A-z])$/;

console.log(RE.test('-hyphen'), false);
console.log(RE.test('hyphen-'), false);
console.log(RE.test('lt4'), false);
console.log(RE.test('morethan21-morethan21-morethan21-morethan21-morethan21'), false);
console.log(RE.test('23123'), false);
console.log(RE.test('231-23'), false);
console.log(RE.test('[\]^_`'), false);
console.log(RE.test('H231-23'), true);
console.log(RE.test('2s31-23'), true);

感谢这个答案提供了一个正向预查的东西(?=.*[A-z])


console.log(RE.test('[\]^_`'), false); 的结果不正确。 - Niet the Dark Absol
1
虽然你在第一次中确实进行了更正,但是你回答的其余部分仍然引用了错误的 [A-z] - Niet the Dark Absol

0

我看到了很多问题和答案,但是我无法给出一个好的答案。 我发现有些人没有遵守域名注册规则,比如(在域名中不能连续使用“-”,但可以使用多次。例如:www.my--domain-name.com 是错误的,而 www.my-domain-name.com 是正确的)。 例如,我看到了这个链接 What is a good regular expression to match a URL? 但它有一些问题。 我使用了这段代码 (https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,}) 但是我无法解决我的问题。

我在asp.net中使用了这个正则表达式,它对我非常有效:

^[(((ftp|http|https):\/\/)?(?:www\.|(?!www))[\u0061-\u007a\u0041-\u005a\u0030-\u0039 \u2000-\u200f\u2028-\u202f\u0621-\u0628\u062a-\u063a\u0641-\u0642\u0644-\u0648\u064e-\u0651\u0655\u067e\u0686\u0698\u06a9\u06af\u06be\u06cc\u06f0-\u06f9\u0629\u0643\u0649-\u064b\u064d\u06d5\u0660-\u0669\u005c]+(-[\u0061-\u007a\u0041-\u005a\u0030-\u0039 \u2000-\u200f\u2028-\u202f\u0621-\u0628\u062a-\u063a\u0641-\u0642\u0644-\u0648\u064e-\u0651\u0655\u067e\u0686\u0698\u06a9\u06af\u06be\u06cc\u06f0-\u06f9\u0629\u0643\u0649-\u064b\u064d\u06d5\u0660-\u0669\u005c]+)*\.[^\s^_]{2,}|www\.[\u0061-\u007a\u0041-\u005a\u0030-\u0039 \u2000-\u200f\u2028-\u202f\u0621-\u0628\u062a-\u063a\u0641-\u0642\u0644-\u0648\u064e-\u0651\u0655\u067e\u0686\u0698\u06a9\u06af\u06be\u06cc\u06f0-\u06f9\u0629\u0643\u0649-\u064b\u064d\u06d5\u0660-\u0669\u005c]+(-[\u0061-\u007a\u0041-\u005a\u0030-\u0039 \u2000-\u200f\u2028-\u202f\u0621-\u0628\u062a-\u063a\u0641-\u0642\u0644-\u0648\u064e-\u0651\u0655\u067e\u0686\u0698\u06a9\u06af\u06be\u06cc\u06f0-\u06f9\u0629\u0643\u0649-\u064b\u064d\u06d5\u0660-\u0669\u005c]+)*\.[^\s^_]{2,}|((ftp|http|https):\/\/)?(?:www\.|(?!www))[\u0061-\u007a\u0041-\u005a\u0030-\u0039 \u2000-\u200f\u2028-\u202f\u0621-\u0628\u062a-\u063a\u0641-\u0642\u0644-\u0648\u064e-\u0651\u0655\u067e\u0686\u0698\u06a9\u06af\u06be\u06cc\u06f0-\u06f9\u0629\u0643\u0649-\u064b\u064d\u06d5\u0660-\u0669\u005c]+(-[\u0061-\u007a\u0041-\u005a\u0030-\u0039 \u2000-\u200f\u2028-\u202f\u0621-\u0628\u062a-\u063a\u0641-\u0642\u0644-\u0648\u064e-\u0651\u0655\u067e\u0686\u0698\u06a9\u06af\u06be\u06cc\u06f0-\u06f9\u0629\u0643\u0649-\u064b\u064d\u06d5\u0660-\u0669\u005c]+)*\.[^\s^_]{2,}|www\.[\u0061-\u007a\u0041-\u005a\u0030-\u0039 \u2000-\u200f\u2028-\u202f\u0621-\u0628\u062a-\u063a\u0641-\u0642\u0644-\u0648\u064e-\u0651\u0655\u067e\u0686\u0698\u06a9\u06af\u06be\u06cc\u06f0-\u06f9\u0629\u0643\u0649-\u064b\u064d\u06d5\u0660-\u0669\u005c]+(-[\u0061-\u007a\u0041-\u005a\u0030-\u0039 \u2000-\u200f\u2028-\u202f\u0621-\u0628\u062a-\u063a\u0641-\u0642\u0644-\u0648\u064e-\u0651\u0655\u067e\u0686\u0698\u06a9\u06af\u06be\u06cc\u06f0-\u06f9\u0629\u0643\u0649-\u064b\u064d\u06d5\u0660-\u0669\u005c]+)*\.[^\s^_]{2,}]{1,2083}$

当然,我的正则表达式是专门针对波斯语的,如果你想将其用于英语,你必须使用这个:

^[(((ftp|http|https):\/\/)?(?:www\.|(?!www))[\u0061\u002d\u007a\u0041\u002d\u005a\u0030\u002d\u0039]+(-[\u0061\u002d\u007a\u0041\u002d\u005a\u0030\u002d\u0039]+)*\.[^\s^_]{2,}|www\.[\u0061\u002d\u007a\u0041\u002d\u005a\u0030\u002d\u0039]+(-[\u0061\u002d\u007a\u0041\u002d\u005a\u0030\u002d\u0039]+)*\.[^\s^_]{2,}|((ftp|http|https):\/\/)?(?:www\.|(?!www))[\u0061\u002d\u007a\u0041\u002d\u005a\u0030\u002d\u0039]+(-[\u0061\u002d\u007a\u0041\u002d\u005a\u0030\u002d\u0039]+)*\.[^\s^_]{2,}|www\.[\u0061\u002d\u007a\u0041\u002d\u005a\u0030\u002d\u0039]+(-[\u0061\u002d\u007a\u0041\u002d\u005a\u0030\u002d\u0039]+)*\.[^\s^_]{2,}]{1,2083}$

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接