我正在尝试使用JavaScript验证<textarea>
的内容,因此我创建了一个validate()
函数,该函数返回true
或false
textarea是否有效。
textarea只能包含以逗号分隔的主机名。通过主机名,我的意思是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
。
有没有办法实现这个目标?也许没有使用RegExps,即使我更喜欢使用一个RegExp。
答案 0 :(得分:2)
说不使用正则表达式的答案非常好,但我喜欢正则表达式:
^\s*(?:(?:\w+(?:-+\w+)*\.)+[a-z]+)\s*(?:,\s*(?:(?:\w+(?:-+\w+)*\.)+[a-z]+)\s*)*$
是的..它不那么漂亮。但它有效 - 在http://regex101.com
上对您的示例案例进行了测试编辑:好的,让我们分解吧。并且只允许sub-domain-01.com
和a--b.com
而不是-.com
每个子域名:\w+(?:-+\w+)*
匹配单词字符串以及可选的前面带有破折号的单词。
每个主机名:\s*(?:(?:\w+(?:-\w+)*\.)+[a-z]+)\s*
一堆子域名后跟一个点。然后最后只跟一串字母(tld)。当然还有两侧的可选空间。
整件事:\s*(?:(?:\w+(?:-\w+)*\.)+[a-z]+)\s*(?:,\s*(?:(?:\w+(?:-\w+)*\.)+[a-z]+)\s*)*
一个主机名,后跟0个或更多,hostname
个逗号分隔列表。
非常简单。
答案 1 :(得分:1)
虽然@dandavis的回答/评论令人印象深刻,但我们可以将其分解为步骤。
trim()
前导和结尾空格中获取值。/\s+/g
用一个空格替换所有空格。意思是找出每个空格发生一次或多次。,<space>
或<space>,<space>
拆分。 Split返回数组。
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.
&#13;
<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>
&#13;
答案 2 :(得分:1)
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()
匹配您指定的每个示例,但&#34; dom-ain.it,domain.com,domain.eu.org.something&#34;因为&#34;某事&#34;无效。
JSFiddle:http://jsfiddle.net/nesutqjf/2/
答案 3 :(得分:0)
我不会为此使用正则表达式,因为您要检查不同规则的很多。当你只有一些非常容易表达的规则但是很难写出“解析代码”时,Regexp很好。
我只是做hostnames.split(',').forEach(validateHostname);
,正如大多数评论所暗示的那样,并且在validateHostname
里面拒绝任何在中间有空格的主机名,两个相邻的点,没有点,以点结尾,有非ASCII字符,在最后一个以点分隔的标记中有数字,依此类推。
这样的函数比正则表达式更容易添加新规则。
答案 4 :(得分:0)
我一直在使用这种模式,似乎也适合你的情况:
/^[a-zA-Z0-9][a-zA-Z0-9\-_]*\.([a-zA-Z0-9]+|[a-zA-Z0-9\-_]+\.[a-zA-Z]+)+$/gi
逻辑很简单:
^[a-zA-Z0-9]
:网址必须以字母数字字符[a-zA-Z0-9\-_]*
:第一个字母数字字符后跟零个或多个字符:字母数字字符,下划线或短划线\.
:第一件必须跟着一段时间。[a-zA-Z0-9]+
:一个或多个字母数字字符,或[a-zA-Z0-9\-_]+\.[a-zA-Z0-9]+
:一个或多个字母数字字符,下划线或短划线,后跟句点和一个或多个字母数字字符您可以在以下代码段中检查此模式是否适用于您的大多数网址。我是怎么做的,与其他人描述的策略类似:
,
字符$.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>
答案 5 :(得分:0)
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>