正则表达式是一种描述性语言的规则来检测字符串的写法是否符合标准。
1、\d,\w,\s,[a-zA-Z0-9],\b,.,*,+,?,x{3},^$
分别是什么?
-
\d
:匹配数字; -
\w
:匹配字母,数字,下划线; -
\s
:匹配空格,Tab,\t等空字符; -
[a-zA-z0-9]
:匹配所有的英文字母与数字; -
\b
:匹配单词边界; -
.
:匹配任意字符; -
*
:匹配任意数量的字符; -
+
:匹配至少有一个先关字符; -
?
:设置非贪婪匹配; -
x{3}
; 匹配3个x; -
^$
; 规定^
后面与$
前面分别是正则匹配的头和尾部; - 各种/W,/S,/D等大写字母代表了小写字母的反义,例如/W代表匹配除了字母,数字,下划线以外的一切字符。
2、贪婪模式和非贪婪模式指什么?
先来看一段代码及其结果:
var a = /^(\d+)(0*)$/
a.exec(1254000) // ["1254000", "1254000", ""]
这段代码所期望的结果应该是将前面的数字和0分开,但是由于正则表达式默认的方式为贪婪匹配,它会默认将前面的匹配规则尽可能匹配最大化,因为0
也属于/d
,故/d
就把后面所有的0顺带的匹配了。所以我们需要使用?
来进行非贪婪匹配,其意思是尽可能少的按照当前规则匹配:
var a = /^(\d+?)(0*)$/
a.exec(1254000) // ["1254000", "1254", "000"]
3、写一个函数trim(str),去除字符串两边的空白字符
法一:
function trim(str){
var arr = str.split(/\s+/g);
for(var i = 0; i < arr.length; i++){
if(arr[i] == ""){
arr.splice(i,1);
i--;
}
}
return arr.join(" ");
}
trim(" 1 2 3 4 5 ")
法二:
function trim(str){
str = str.split(/\s+/g).join(" ");
str = str.replace(/^\s+|\s+$/g,"");
return str;
}
trim(" 1 2 3 4 5 ");
4、使用实现 addClass(el, cls)、hasClass(el, cls)、removeClass(el,cls),使用正则:
function addClass(el, cls){ //cls是新的类名,el是DOM元素
var re = new RegExp('(\\s|^)' + cls + '(\\s|$)','g');
if (! re.test(el.className) ){
el.className += " " + cls;
}
else {
console.log("hasclass " + cls);
}
}
function hasClass(el,cls){
var re = new RegExp('(\\s|^)' + cls + '(\\s|$)','g');
if ( re.test(el.className)){
return true;
}
else {
return false;
}
}
function removeClass(el,cls) {
var re = new RegExp('(\\s|^)' + cls + '(\\s|$)','g');
if ( re.test(el.className)){
el.className = el.className.replace((" " + cls)||(cls + " ") ,"");
}
else{
console.log("has no class "+ cls);
}
}
这里有几个要注意的地方:
- 从外部想要向正则表达式传递数据时,用
var reg = / /
的方法是没法传递的,所以只能用创立原型的办法,var reg = new RegExp()
。 - 由于
RegExp
在此传递的参数为字符串格式,‘(\\\s|^)’
代表了字符串形式的\s或^,后面的同理。 - g代表了全局搜索(globle),此参数位置还可以传递i(ignore)忽略大小写和m(multiply)多行搜索(这个得和g一块用才能显现效果)
5、写一个函数isEmail(str),判断用户输入的是不是邮箱
function isEmail(str){
var email = /(\w+)@(\w+).(\w+)/
return email.test(str);
}
6、写一个函数isPhoneNum(str),判断用户输入的是不是手机号
function isPhoneNum(num){
var tel = /^1[3,5,8]\d{9}$/;
return tel.test(num);
}
7、写一个函数isValidUsername(str),判断用户输入的是不是合法的用户名(长度6-20个字符,只能包括字母、数字、下划线)
function isValidUsername(str){
var username = /^\w{6,20}$/;
return username.test(str);
}
8、写一个函数isValidPassword(str), 判断用户输入的是不是合法密码(长度6-20个字符,包括大写字母、小写字母、数字、下划线至少两种)
function isValidPassword(str){
var fundenmental = /[\w]{6,20}/;
var w = /[a-z]{6,20}/,
W = /[A-Z]{6,20}/,
num = /[0-9]{6,20}/,
line = /[_]{6,20}/;
if(fundenmental.test(str)){ //先判断是否为6-20的下划线,数字,字母的构成
if(w.test(str) | W.test(str) | num.test(str) | line.test(str)){ //再判断是否仅是单个特性的构成
return false;
}
else {
return true;
}
}
else {
return false;
}
}
9、写一个正则表达式,得到如下字符串里所有的颜色(#121212)
var re = /#[0-9a-zA-z]{6}/g;
var subj = "color: #121212; background-color: #AA00ef; width: 12px; bad-colors: f#fddee #fd2 "
alert( subj.match(re) )
10、下面代码输出什么? 为什么? 改写代码,让其输出hunger, world
var str = 'hello "hunger" , hello "world"';
var pat = /".*"/g;
str.match(pat); //["hunger" ,hello "world"]
由于.
能匹配任何字符,*
能匹配任意数量的字符,而正则匹配又是默认的贪婪匹配,所以从第一个"
开始都是.*
所匹配的,故我们需要修改为非贪婪模式:
var str = 'hello "hunger" , hello "world"';
var pat = /".*?"/g;
str.match(pat); //[""hunger"", ""world""]
11、补全如下正则表达式,输出字符串中的注释内容. (可尝试使用贪婪模式和非贪婪模式两种方法)
str = '.. <!-- My -- comment \n test --> .. <!----> .. '
re = /.. your regexp ../
str.match(re) // '<!-- My -- comment \n test -->', '<!---->'
贪婪模式:
str = '.. <!-- My -- comment \n test --> .. <!----> .. '
re = /<!--[^\.]*/g; //匹配“<!-- 非.的所有字符”,遇到.停止。
str.match(re);
非贪婪模式:
str = '.. <!-- My -- comment \n test --> .. <!----> .. '
re = /<!--[^\.]*?-->/g; //匹配“<!-- 非.的所有字符-->”
str.match(re);
12、补全如下正则表达式:
var re = /* your regexp */
var str = '<> <a href="/"> <input type="radio" checked> <b>'
str.match(re) // '<a href="/">', '<input type="radio" checked>', '<b>'
答案:
var re = /<[^>]+?>/g; //这里必须使用非贪婪匹配;
var str = '<> <a href="/"> <input type="radio" checked> <b>';
str.match(re); // '<a href="/">', '<input type="radio" checked>', '<b>'