有人知道如何编写一个正则表达式,只允许使用 a-zA-Z0-9.-(字母、数字、点和短横线),但不能以点或短横线开头或结尾吗?
我尝试了这个:
/^[^.-][a-zA-Z0-9.-]+[^.-]$/
...但是如果我写类似"john@"这样的内容,它会生效,而我不想这样做,因为@是不允许的。
有人知道如何编写一个正则表达式,只允许使用 a-zA-Z0-9.-(字母、数字、点和短横线),但不能以点或短横线开头或结尾吗?
我尝试了这个:
/^[^.-][a-zA-Z0-9.-]+[^.-]$/
...但是如果我写类似"john@"这样的内容,它会生效,而我不想这样做,因为@是不允许的。
根据相关的互联网建议(RFC3986第2.2节,该节参考了RFC1034第3.5节和RFC1123第2.1节),子域名(DNS域名主机名的一部分)必须满足以下几个要求:
[A-Za-z]
或数字[0-9]
)开头和结尾。以下是一个满足这些要求的子域名部分的表达式片段:
[A-Za-z0-9](?:[A-Za-z0-9\-]{0,61}[A-Za-z0-9])?
请注意,此表达式片段不能单独使用 - 它需要在更大的上下文中结合边界条件,如下所示表达式验证DNS主机名...
命名的主机(而不是IP地址)必须满足以下附加要求:
因此,以下是一个有注释的正则表达式(使用PHP语法),可以伪验证DNS主机名:(请注意,这里结合了上面的子域名部分的修改版本,并对其进行了注释)。
更新时间:2016年8月20日:由于本回答最初发布于2011年,顶级域名数量已经激增。截至2016年8月,现在已有超过1400个顶级域名。原本回答中的正则表达式包含了所有这些内容,但这已不再实际可行。下面的新正则表达式包含了不同的顶级域名表达式。该算法来自:顶级域名规范草案-liman-tld-names-06。
$DNS_named_host = '%(?#!php/i DNS_named_host Rev:20160820_0800)
# Match DNS named host domain having one or more subdomains.
# See: https://dev59.com/BWsz5IYBdhLWcg3wZm3Q#7933253
^ # Anchor to start of string.
(?!.{256}) # Whole domain must be 255 or less.
(?: # One or more sub-domains.
[a-z0-9] # Subdomain begins with alpha-num.
(?: # Optionally more than one char.
[a-z0-9-]{0,61} # Middle part may have dashes.
[a-z0-9] # Starts and ends with alpha-num.
)? # Subdomain length from 1 to 63.
\. # Required dot separates subdomains.
)+ # End one or more sub-domains.
(?: # Top level domain (length from 1 to 63).
[a-z]{1,63} # Either traditional-tld-label = 1*63(ALPHA).
| xn--[a-z0-9]{1,59} # Or an idn-label = Restricted-A-Label.
) # End top level domain.
$ # Anchor to end of string.
%xi'; // End $DNS_named_host.
^\w(?:[\w-]{0,61}\w)?$
非常有效,事实上srv记录要求它们以避免与普通子域冲突 2. fyi双破折号是punycode所必需的。当然,您可以将这些验证限制为某些记录类型,但是您将不得不编写一个小解析器之类的东西,这也将允许您检查当前tld列表是否匹配 :) - sg3s您希望将首尾字符限制为字母数字。您当前的设置允许首尾字符除了点和破折号以外的任何字符。以下设置符合您的需求:
/^[a-zA-Z0-9][a-zA-Z0-9.-]+[a-zA-Z0-9]$/
/^\w[\w.-]+\w$/i
。 - RReverser /^([a-zA-Z0-9]([-a-zA-Z0-9]{0,61}[a-zA-Z0-9])?\.)?([a-zA-Z0-9]{1,2}([-a-zA-Z0-9]{0,252}[a-zA-Z0-9])?)\.([a-zA-Z]{2,63})$/
需要通过以下chai测试:
const expect = require('chai').expect;
function testDomainValidNamesRegExp(val) {
let names = /^([a-zA-Z0-9]([-a-zA-Z0-9]{0,61}[a-zA-Z0-9])?\.)?([a-zA-Z0-9]([-a-zA-Z0-9]{0,252}[a-zA-Z0-9])?)\.([a-zA-Z]{2,63})$/;
return names.test(val);
}
let validDomainNames = [
"example.com",
"try.direct",
"my-example.com",
"subdomain.example.com",
"example.com",
"example23.com",
"regexp-1222.org",
"read-book.net",
"org.host.org",
"org.host.org",
"velmart.shop-products.md",
"ip2email.terronosp-222.lb",
"stack.com",
"sta-ck.com",
"sta---ck.com",
"9sta--ck.com",
"sta--ck9.com",
"stack99.com",
"99stack.com",
"sta99ck.com",
"sub.do.com",
"ss.sss-ss.ss",
"s.sss-ss.ss",
"s.s-s.ss",
"test.t.te"
];
let invalidDomainNames = [
"example2.com222",
"@example.ru:?",
"example22:89",
"@jefe@dd.ru@22-",
"example.net?1222",
"example.com:8080:",
".example.com:8080:",
"---test.com",
"$dollars$.gb",
"sell-.me",
"open22.the-door@koll.ru",
"mem-.wer().or%:222",
"pop().addjocker.lon",
"regular-l=.heroes?",
" ecmas cript-8.org ",
"example.com::%",
"example:8080",
"example",
"examaple.com:*",
"-test.test.com",
"-test.com",
"dd-.test.com",
"dfgdfg.dfgdf33.e",
"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd-.test.com",
"dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd.testttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt.com",
"d-.test.com"
];
describe("Test Domain Valid Names RegExp", () => {
validDomainNames.forEach((val) => {
it(`Text: ${val}`, () => {
expect(testDomainValidNamesRegExp(val)).to.be.true;
});
});
});
describe("Test Domain Invalid Names RegExp", () => {
invalidDomainNames.forEach((val) => {
it(`Text: ${val}`, () => {
expect(testDomainValidNamesRegExp(val)).to.be.false;
});
});
});
非常欢迎更多的测试!
^([A-Za-z0-9](?:(?:[-A-Za-z0-9]){0,61}[A-Za-z0-9])?(?:\.[A-Za-z0-9](?:(?:[-A-Za-z0-9]){0,61}[A-Za-z0-9])?){2,})$
服务器 Ruby
\A([A-Za-z0-9](?:(?:[-A-Za-z0-9]){0,61}[A-Za-z0-9])?(?:\.[A-Za-z0-9](?:(?:[-A-Za-z0-9]){0,61}[A-Za-z0-9])?){2,})\z
试试这个:
/^[a-zA-Z0-9][a-zA-Z0-9.-]*[a-zA-Z0-9]$/
但是字符串至少要有2个字符才能匹配:a a-zA-Z0-9和a a-zA-Z0-9。为了避免这种情况,您可以使用以下正则表达式:
/^[a-zA-Z0-9][a-zA-Z0-9.-]*$/
但是你必须进行额外的检查,以确保字符串的结尾既不是点也不是破折号。
这里是用于子域名的正则表达式,
允许字符串中包含字母和数字
^[a-zA-Z0-9]+[a-zA-Z0-9-._]*[a-zA-Z0-9]+$
正确的示例
错误的例子
https://abcxyz.com
/^[a-zA-Z0-9][a-zA-Z0-9.-]*[a-zA-Z0-9]$/
。你代码的问题在于起始和结束的[^.-]
匹配除了'.'或'-'之外的任何字符,这将匹配所有字符而不仅仅是[a-zA-Z0-9]
。^(?![-.])[a-zA-Z0-9.-]+(?<![-.])$
如果您想针对子域名尝试,请使用以下方法:
(^[a-zA-Z0-9][a-zA-Z0-9]*)+(([.][a-zA-Z0-9]+)*([-]+[a-zA-Z0-9]+)*([_]+[a-zA-Z0-9]+)*)*$
解释:
(^[a-zA-Z0-9][a-zA-Z0-9]*)+
以字母或数字字符开头,后跟 0 到无限个字母或数字字符,至少出现一次。
([.][a-zA-Z0-9]+)*
可选:一个点后面跟着0个或多个字母数字字符。
([-]+[a-zA-Z0-9]+)*
可选:一个或多个“-”后面跟着0个或多个字母数字字符。
([_]+[a-zA-Z0-9]+)*
可选:一个或多个“_”后面跟着0个或多个字母数字字符。
/^\w[\w-]+\w$/