一直以来都没有太把正则表达式当回事,两次面试被问及时回答的都是需要用的时候百度。总觉得这很不对,所以学习并总结一遍。
正则表达式的字面量表示
var expression = /pattern/flags;
flags
g—全局匹配
i—不区分大小写
m—多行模式
字符边界
有时需要确认一个模式是以特定的字符开头或结束的。
^ 匹配字符的开头,$ 匹配字符的结尾
/^a/.test('abcde'); // true /^a$/.test('abcde'); // false /^a$/.test('a'); // true
转义字符 \b 也可以匹配“字符边界”,它与 (^,$) 有些类似,只不过 \b 除了可以匹配开头和结尾,还可以匹配空格与标点。
/\bxyx\b/.test('abc,xyx,def'); // true
范围查找
如果需要匹配某个区间内的字符可以使用 [] 符号
[0-9] 匹配 0 到 9 之间的数字
[a-z] 匹配 a 到 z 之间的字符
[A-Z] 匹配 A 到 Z 之间的字符
[A-z] 匹配 A 到 z 之间的字符(大写在小写之前应该是大写字母的ASCII码值小吧)
[adksgd] 匹配其实任意一个字符
var reg = /[adksgd]/; reg.test('as'); // true
重复模式
给元素后面加上重复符号表示重复匹配若干次
(*) 匹配任意次数(包括零次)
(+) 至少匹配一次
(?) 表示可选(一次或零次)
需要指定次数可以使用 {n,m}。
{n} 匹配 n 次
{n,m} 匹配 n-m次
{n,} 最少出现 n 次
{,m} 最多出现m次
子表达式分组
在同一表达式里,需要对多个字符使用 * 或 + 这样的特殊字符。可以使用小括号进行分组。
var minionsSay = /ba(na)+/i; minionsSay.test('Banananananana!'); // true
多选一
使用 (|) 表示允许模式在多个元素中选择一个。
var sayColor = /\bcolor is (red|blue|yellow)\b/; sayColor.test('color is blue'); // true
常用的元字符
(.) 用来表示“任何不是换行符的字符”
(\d) 表示“任意数字”
(\w) 匹配任何单词(任何英文、数字、下划线构成的字符)
(\s) 匹配任何空字符(Tab、换行和空格等)
(\b) 匹配单词边界
反模式
对元字符中的字母进行大写就可以实现反模式
(\D) 匹配非数字字符
(\W) 匹配非单词字符
(\S) 匹配任何非空字符
(\D) 匹配非单词边界
[^xxx] 匹配非中括号中的内容,只要出现其中一个字符即匹配失败
方法汇总
有关正则表达式的方法,有些是绑定正则实例上,有些是绑定在字符串本身上。
正则表达式方法:
test
检索字符串是否符合正则规范,返回布尔值。
var reg = /^a$/i; var result = reg.test('A'); console.log(result); // true
exec
检索字符串中指定的值,返回匹配的值,并指定所在的位置。
var test = 'A, B, C, D, E';
var result = /\bc\b/i.exec(test);
console.log(result); // ["C", index: 6, input: "A, B, C, D, E"]
result 的第1项为匹配到的字符串,index 属性表示匹配到的位置,input 属性表示应用匹配的字符串。如果匹配失败,result 值为 null;
需要注意的是,如果对同一字符串调用 exec 方法,申明了全局模式 (g)的话每次开始匹配的位置都在上一次匹配结束的位置,反之从头开始匹配。
var text = 'cat, bat, sat, fat',
pattern1 = /.at/,
result = pattern1.exec(text);
console.log(result); //["cat", index: 0, input: "cat, bat, sat, fat"]
result = pattern1.exec(text);
console.log(result); //["cat", index: 0, input: "cat, bat, sat, fat"]
var pattern2 = /.at/g;
result = pattern2.exec(text);
console.log(result); //["cat", index: 0, input: "cat, bat, sat, fat"]
result = pattern2.exec(text);
console.log(result); //["bat", index: 5, input: "cat, bat, sat, fat"]
exec 方法同时也会匹配子模式的字符串,并按顺序存入数组中。下例为对美式日期进行格式化的一个函数。
function formatDate(string) { var result = /\b(\d+)\/(\d+)\/(\d{4})\b/.exec(string); if (result == null) { return; } console.log(result); // ["8/6/2016", "8", "6", "2016", index: 0, input: "8/6/2016"] var date = new Date(Number(result[3]), Number(result[2]), Number(result[1])); date = date.getFullYear() + '-' + date.getMonth() + '-' + date.getDate(); return date; } console.log(formatDate('8/6/2016')); // 2016-6-8
字符串方法:
search
检索并返回匹配字符所在字符串的位置索引值,与 indexOf 方法相似,只是接收的参数为正则实例对象。
var index = 'doubleKill'.search(/ek/i); console.log(index); // 5
match
与上文中的 exec 方法很相似,只不过 exec 方法在正则对象上,而 match 方法在字符串上。
返回值也相同。
replace
将匹配正则的字符部分进行替换,要注意的是若没有申明全局模式 (g),只会替换第一个匹配的字符。
var reg = /a(b|c)/g, str = 'abDDacDD'; var result = str.replace(reg, 'A'); console.log(result); // ADDADD
replace 方法与正则相配合可以实现许多强大的功能,同时 replace 方法的第二个参数可以是函数,函数return的值即为替换后的值。
var text = 'The sun and the moon', result = text.replace(/\b(sun|moon)\b/g, function(str) { return str.toUpperCase(); }); console.log(result); // The SUN and the MOON
我们使用该方法来编写一个对输入字符转义,防范XSS的函数
function (text) { var replacements = { '<': '<', '>': '>', '&': '$amp;', '\"': '"' }; return text.replace(/[<>&"]/g, function(str) { return replacements[str]; }); }
构造函数模式
除了字面量形式的正则表达式,还可能通过 RegExp 构造函数的方法创建。
var pattern1 = /[bc]at/i; var pattern2 = new RegExp('[bc]at','i');
RegExp 构造函数接收两个参数,第一个是正则的字符串表示,第二个是flag。由于接收的是字符串形式,所以正则表达式中出现的转义字符要进行双重转义。
var pattern1 = /^\[abc\]$/i; pattern1.test('[ABC]'); // true var pattern2 = new RegExp('^\\[abc\\]$', 'i'); pattern2.test('[ABC]'); //true
动态创建RegExp
有时候需要匹配的正则模式不是固定的,这种情况下就不好使用正则的字面量写法了。
var text = '1,2,3,4,5,6,7,8,9,0', randomNum = Math.floor(Math.random() * 10), result = text.replace(new RegExp('\\b'+randomNum+'\\b'), ' ');
以上代码会随机将一个数字替换为空,这里要注意前面说过的双重转义问题。
感谢你的浏览,希望能对你有所帮助。