现在要让一个文本框只能输入“字母,数字,汉字以及英文的-,_” 并且文本框的第一个字符只能是字母与汉字 最初的实现是这样的
已知有文本框: <input type="text" name="orgName" onKeyUp="maintainEffectiveOrgName
()" id="orgName" value="">
/** * 组织名只能是包含数字,汉字,字母,英文-,_的集合 */ function maintainEffectiveOrgName() { var orgName = document.getElementById("orgName"); var value = orgName.value; var len = value.length; var regexp1 =/[a-zA-Z/u4e00-/u9fa5]/; var regexp = /[a-zA-Z0-9/-_/u4e00-/u9fa5]/g; var regexp2 = /[^a-zA-Z0-9/-_/u4e00-/u9fa5]/g; if(0<len) { //判断第一个字符是否是字母或汉字 if(1==len&&!regexp1.test(value)) { orgName.value=""; alert("第一个字符必须是字母或汉字!") return; } //判断文本框是否输入了非法字符 if( !regexp.test(value)) //Enter的编码是13 { var effectiveStr = value.replace(regexp2,""); orgName.value=effectiveStr; alert("只能输入数字,字母,-,_,汉字这些字符!"); return; } } }
//判断第一个字符是否是字母或汉字 if(1==len&&!regexp1.test(value)) { orgName.value=""; alert("第一个字符必须是字母或汉字!") return; } 明显有问题,只考虑到了文本框只有一个字符的时候,用户可以输入一串合法字符后再在第一个字符输入非法字符,(哈哈,这当然是BT用户的做法或恶意攻击)可是总不能避免输入非法字符了。
修改为 //取字符串第一个字符,也就不再有字符串长度为1的局限 strFirst = value.substring(0,1); if(!regexp1.test(strFirst)) { orgName.value=value.substring(1,value.length); alert("the first char must be number or char!"); return; }
//判断文本框是否输入了非法字符 if( !regexp.test(value)) { var effectiveStr = value.replace(regexp2,""); orgName.value=effectiveStr; alert("只能输入数字,字母,-,_,汉字这些字符!"); return; }
想法是没有错的,但是确实是没有理解javascript的正则表达式的用法 首先看看 var regexp = /[a-zA-Z0-9/-_/u4e00-/u9fa5]/g的定义 注意这个[]的语法含义:匹配在字符集合中出现的任何一个字符的一次出现
所以字符串中只要有一个满足条件,就会返回真 对应我的程序regexp.test(value) 如果value="abc",当然是返回真 但如果是"abc*"呢,还是返回true,因为一个a就足够拉,因为他就满足拉匹配的要求 所以必须对[]要这样的理解。是字符串中只要有一个匹配正则表达式就返回true,即使另
外有n个不匹配,也没有关系,它还是返回true. 所以不是“要字符串的所有字符都匹配正则表达式才返回真”的理解是错误的
所以后来我们改成 var regexp = /[^a-zA-Z0-9/-_/u4e00-/u9fa5]/g; if( regexp.test(value)) { //将所有非法字符清空 var effectiveStr = value.replace(regexp,""); orgName.value=effectiveStr; alert("只能输入数字,字母,-,_,汉字这些字符!") }
其实就是将regexp=regexp2 所以只要value有一个字符是满足regexp的要求,就返回true
其实这个时候也可以修改判断第一个字符是否是字母或汉字的方法 如下修改 var regexp1 =/[^a-zA-Z/u4e00-/u9fa5]/; var last = value.substring(0,1); if( regexp.test(last)) { // alert(value.substring(1)); orgName.value=value.substring(1); alert("第一个字符必须是字母或汉字!") } 不作解析拉,自己慢慢体会
所以最终的方法实现是
function maintainEffectiveOrgName() { var orgName = document.getElementById("orgName"); var value = orgName.value; var len = value.length; var regexp1 =/[^a-zA-Z/u4e00-/u9fa5]/; var regexp = /[^a-zA-Z0-9/-_/u4e00-/u9fa5]/g; if(0<len) { var last = value.substring(0,1); if( regexp.test(last)) { orgName.value=value.substring(1); alert("第一个字符必须是字母或汉字!") } else { if( regexp.test(value)) { var effectiveStr = value.replace(regexp,""); orgName.value=effectiveStr; alert("只能输入数字,字母,-,_,汉字这些字符!") } } } }
这个按说已经没问题,但是却有种特殊情况,当文本框为空,用户拷贝一段字符,其中包含若干空格字符,如果仍然只是去掉拉一个字符,还有若干个空格字符保留在文本框内,这就是没理解/g的原因,如果没有/g就只会作一次匹配。只有/g才能全局匹配,所以 var regexp1 =/[^a-zA-Z/u4e00-/u9fa5]/; 必须改为
var regexp1 =/[^a-zA-Z/u4e00-/u9fa5]/g;