正则表达式以匹配逗号分隔的主机名
RegExp to match comma separated hostnames
问题
我正在尝试使用 JavaScript 验证<textarea>
的内容,所以我创建了一个 validate()
函数,该函数返回true
或false
文本区域内的文本是否有效。
文本区域只能包含逗号分隔的主机名。主机名的意思是类似于 subdomain.domain.com
,所以它基本上是一些点分隔的字符串。由于用户往往写得不是很好,我还希望允许在各种主机名和逗号之间留下任意数量的空格,但不要在主机名内。
以下是一些应该匹配或不应该匹配的示例:
-
应匹配:
-
domain.com,domain2.co.vu,sub.domain.org
-
domai2n.com , dom-ain.org.co.vu.nl ,domain.it
-
dom-ain.it, domain.com, domain.eu.org.something
-
a.b.c, a.b, a.a.a , a.r
-
0191481.com
-
-
不应匹配:
-
domain.com., sub.domain.it
不完整的主机名 -
domain.me, domain2
不完整的主机名 -
sub.sub.sub.domain.tv, do main.it
主机名包含空格 -
site
不完整的主机名 -
hèy.com
主机名不能包含重音符号 -
hey.01com
主机名不能以数字结尾或包含数字的字符串 -
hello.org..wow
不完整的主机名
-
到目前为止我尝试过什么
我使用以下代码构建了我的函数:
function validate(text) {
return (
(/^([a-z0-9'-'.]+ *, *)*[a-z0-9'-'.]+[^, ]$/i.test(text)
&& !/'.[^a-z]|'.$/i.test(text)
&& ~text.indexOf('.'))
);
}
不幸的是,我的函数不起作用。它无法识别不完整的主机名并返回true
。
有什么方法可以做到这一点吗?也许不使用正则表达式,即使我更喜欢使用单个正则表达式。
说不使用正则表达式的答案非常好,但我喜欢正则表达式,所以:
^'s*(?:(?:'w+(?:-+'w+)*'.)+[a-z]+)'s*(?:,'s*(?:(?:'w+(?:-+'w+)*'.)+[a-z]+)'s*)*$
是的。。没那么漂亮。但它有效 - 在您的样品盒上进行了测试 http://regex101.com
编辑:好的,让我们分解一下。并且只允许sub-domain-01.com
和a--b.com
,不允许-.com
每个子域 thingo: 'w+(?:-+'w+)*
匹配单词字符字符串以及一些前面带有破折号的单词(可选)。
每个主机名:'s*(?:(?:'w+(?:-'w+)*'.)+[a-z]+)'s*
一堆子域 thingos 后跟一个点。最后只跟一串字母(TLD)。当然还有两侧的可选空间。
整件事:'s*(?:(?:'w+(?:-'w+)*'.)+[a-z]+)'s*(?:,'s*(?:(?:'w+(?:-'w+)*'.)+[a-z]+)'s*)*
一个主机名,后跟 0 或更多 ,hostname
s作为我们的逗号分隔列表。
真的很简单。
虽然@dandavis的回答/评论令人印象深刻,但让我们将其分解为步骤。
- 从文本区域获取值,并
trim()
前导空格和结尾空格。 - 使用
/'s+/g
将所有空格替换为单个空格。 表示查找出现一次或多次的每个空格。 - 按
,<space>
或<space>,<space>
拆分。拆分返回数组。 - 使用过滤器迭代每个数组元素
- 检查元素是否为有效域。如果是这样,请将其退回。
var domains = document.querySelector("textarea").value;
domains = domains.trim().replace(/'s+/g, " ").split(/'s?,'s/);
var domainsTested = domains.filter(function(element){
if (element.match(/^[a-zA-Z0-9][a-zA-Z0-9-_]{0,61}[a-zA-Z0-9]{0,1}'.([a-zA-Z]{1,6}|[a-zA-Z0-9-]{1,30}'.[a-zA-Z]{2,3})$/))
{
return element;
}
})
document.write(domainsTested.join(" | ")); //this is just here to show the results.
document.write("<br />Domainstring is ok: " + (domainsTested.length == domains.length)); //If it's valid then this should be equal.
<textarea style="width: 300px; height: 100px">www.example.com , example.com, example.ca, example, example.com example.nl www.example, www.exam ple.com, sub.sub.sub.domain.tv, do main.it, sub.domain.tv</textarea>
function validate() {
//Get the user input
var hostnames = document.getElementById('yourtextarea').value;
//Regex to validate hostname
var re = new RegExp(/^([a-zA-Z0-9]([a-zA-Z0-9'-]{0,61}[a-zA-Z0-9])?'.)+[a-zA-Z]{2,6}$/);
//Trim whitespace
hostnames = hostnames.trim();
//Explode into an array
hostnames = hostnames.split(",");
//Loop through array & test each hostname with regex
var is_valid = true;
for (var i=0; i < hostnames.length; i++){
var hostname = hostnames[i].trim();
if (re.test(hostname)) {
is_valid = true; //if valid, continue loop
} else {
is_valid = false; //if invalid, break loop and return false
break;
}
} //end for loop
return is_valid;
} //end function validate()
匹配您指示的每个示例,但"dom-ain.it,domain.com,域.eu.org.something"除外,因为"某些内容"无效。
JSFiddle: http://jsfiddle.net/nesutqjf/2/
我不会为此使用正则表达式,因为您有很多不同的规则要检查。当你只有几个规则时,正则表达式是很好的,这些规则很容易表达,但写成"解析代码"很痛苦。
正如大多数评论所建议的那样,我只会做hostnames.split(',').forEach(validateHostname);
,并且在内部validateHostname
拒绝任何中间有空格、两个相邻点、没有点、以点结尾、具有非 ASCII 字符、在最后一个点分隔标记中有数字的主机名,等等。
像这样的函数将比正则表达式更容易添加新规则。
我已经使用这种模式一段时间了,似乎也适用于您的情况:
/^[a-zA-Z0-9][a-zA-Z0-9'-_]*'.([a-zA-Z0-9]+|[a-zA-Z0-9'-_]+'.[a-zA-Z]+)+$/gi
逻辑很简单:
-
^[a-zA-Z0-9]
:URL 必须以字母数字字符开头 -
[a-zA-Z0-9'-_]*
:第一个字母数字字符后可以跟零个或多个:字母数字字符、下划线或短划线 -
'.
:第一件必须后跟句点。 - 第二件必须遵循相同的模式:
-
[a-zA-Z0-9]+
:一个或多个字母数字字符,或 -
[a-zA-Z0-9'-_]+'.[a-zA-Z0-9]+
:一个或多个字母数字字符、下划线或短划线,后跟句点和一个或多个字母数字字符
-
您可以在以下代码片段中检查此模式是否适用于大多数 URL。我的做法类似于其他人描述的策略:
- 在键上获取文本区域的值(或者您可以绑定提交,模糊,按键,键下,更改等)
- 按
,
字符拆分值 - 使用
$.trim()
删除侧翼空格 - 使用上面的正则表达式模式来评估每个单独的字符串
可选,用于视觉输出:
- 生成网址列表
- 指明输入的每个网址是否有效
$(function() {
$('textarea').keyup(function() {
var urls = $(this).val().split(',');
$('ul').empty();
$.each(urls, function(i,v) {
// Trim URL
var url = $.trim(v);
// RegEx
var pat = /^[a-zA-Z0-9][a-zA-Z0-9'-_]*'.([a-zA-Z0-9]+|[a-zA-Z0-9'-_]+'.[a-zA-Z]+)+$/gi,
test = pat.test(url);
// Append
$('ul').append('<li>'+url+' <span>'+test+'</span></li>');
});
});
});
textarea {
width: 100%;
height: 100px;
}
ul span {
background-color: #eee;
display: inline-block;
margin-left: .25em;
padding: 0 .25em;
text-transform: uppercase;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea placeholder="Paste URLs here"></textarea>
<ul></ul>
一个包含 validate.js
的示例,该示例具有经过良好测试的例程,用于测试有效的 FQDN。或者查看源代码并获取您需要的内容。
function validate (e) {
var target = e.target || e;
target.value.split(',').some(function (item) {
var notValid = !validator.isFQDN(item.trim());
if (notValid) {
target.classList.add('bad');
} else {
target.classList.remove('bad');
}
return notValid;
});
}
var domains = document.getElementById('domains');
domains.addEventListener('change', validate);
validate(domains);
#domains {
width: 300px;
height: 100px;
}
.bad {
background-color: red
}
<script src="http://rawgit.com/chriso/validator.js/master/validator.js"></script>
<textarea id="domains">www.example.com, example.com, example.ca, example, example.com example.nl www.example, www.exam ple.com</textarea>
此正则表达式应符合域的所有要求。它将 TLD 限制为 24 个字符,因为它是目前最长的 TLD,但您可以将其更改为理论上的 63 个字符(然后您必须将"25"更改为"64" - 请记住,它有两个实例):
^'s*(?!.*?_.*?)(?!(?:['d'w]+?'.)?'-['w'd'.'-]*?)(?!['w'd]+?'-'.(?:['d'w'.'-]+?))(?=['w'd])(?=['w'd'.'-]*?'.+['w'd'.'-]*?)(?!['w'd'.'-]{254})(?!(?:'.?['w'd'-'.]*?['w'd'-]{64,}'.)+?)['w'd'.'-]+?(?<!['w'd'-'.]*?'.['d]+?)(?<=['w'd'-]{2,})(?<!['w'd'-]{25})('s*,'s*(?!.*?_.*?)(?!(?:['d'w]+?'.)?'-['w'd'.'-]*?)(?!['w'd]+?'-'.(?:['d'w'.'-]+?))(?=['w'd])(?=['w'd'.'-]*?'.+['w'd'.'-]*?)(?!['w'd'.'-]{254})(?!(?:'.?['w'd'-'.]*?['w'd'-]{64,}'.)+?)['w'd'.'-]+?(?<!['w'd'-'.]*?'.['d]+?)(?<=['w'd'-]{2,})(?<!['w'd'-]{25}))*'s*$
在这里你可以测试它:https://regex101.com/r/ZyPMn4/1
- chrome扩展更改主机/域警告
- javascript函数内部的代码用逗号而不是分号分隔
- 可以't用回车符分隔那个字符串
- 本地主机Typekit JS
- Meteor应用程序无法运行-对象#<编译器>没有方法'主机'
- 如何使用Wordpress'RESTApi访问本地主机上的数据
- 计算输入中有多少逗号分隔的字符串
- 选择带有空格分隔单词的元素
- 尝试使用Javascript正则表达式来获取“&"分隔文本,无论它是否's是最后一个值
- 使用JavaScript分析分隔文本行
- 比较逗号分隔的字符串
- 用于本地主机上进程间通信的Javascript中的UDP
- 本地主机与部署的角度承诺差异
- 用分隔符分隔具有多个整数值的字符串的Javascript"重试错误的值
- chart.js在我的本地主机上运行良好,但无法在线运行
- Javascript-Regex,用于逗号分隔的字母数字
- 使用jquery过滤逗号分隔的span文本
- 造型:主机的聚合物元素与Javascript
- 在javascript中用逗号分隔的字符串分割值
- 正则表达式以匹配逗号分隔的主机名