字符串的正则匹配方法

  • 定位:str.search(regexp),返回某一类集合所在的索引位置(只返回第一个);没有返回-1。
  • 查找:str.match(regexp),返回匹配到的内容(结果是一个数组);没有返回null。(/[0-9]/)或(/[0-9]/g)正则中的全局变量g,决定输出一个还是全部。
  • 替换:str.replace( regexp | substr,newSubstr | function ),正则中的全局参数g决定是否全部替换。
  • 分隔:str.split([separator][,limit]),用separator分隔,返回数组(limit决定输出多少个);separator可以为字符或集合(regexp)。

match()

match()方法只接受一个为正则或字符串的参数,并以数组的形式返回匹配的内容。这个方法类似于正则表达式RegExp的exec()方法,只是调换了RegExp和String对象的位置。若匹配失败,则match()方法返回null。

'x'.match(/y/);  // null

若不设置全局标志,match()方法和exec()方法结果相同

var string = 'cat,bat,sat,fat';
var pattern = /.at/;
var matches = string.match(pattern);
console.log(matches,matches.index,matches.input);  // ['cat'] 0 'cat,bat,sat,fat' 
var matches = string.match(pattern);
console.log(matches,matches.index,matches.input);  // ['cat'] 0 'cat,bat,sat,fat' 
 
var string = 'cat,bat,sat,fat';
var pattern = /.at/;
var exec = pattern.exec(string);
console.log(exec,exec.index,exec.input);  // ['cat'] 0 'cat,bat,sat,fat' 
var exec = pattern.exec(string);
console.log(exec,exec.index,exec.input);  // ['cat'] 0 'cat,bat,sat,fat'

设置全局标志后,exec()方法依然返回单次的匹配结果,而match()方法会返回一个字符串数组,其中包括各次成功匹配的文本,但没有index和input属性。

var string = 'cat,bat,sat,fat';
var pattern = /.at/g;
var matches = string.match(pattern);
console.log(matches,matches.index,matches.input);  // ["cat", "bat", "sat", "fat"] undefined undefined 
var matches = string.match(pattern);
console.log(matches,matches.index,matches.input);  // ["cat", "bat", "sat", "fat"] undefined undefined 
 
var string = 'cat,bat,sat,fat';
var pattern = /.at/g;
var exec = pattern.exec(string);
console.log(exec,exec.index,exec.input);  // ['cat'] 0 'cat,bat,sat,fat' 
var exec = pattern.exec(string);
console.log(exec,exec.index,exec.input);  // ['bat'] 4 'cat,bat,sat,fat'

match()方法作为字符串String的方法,接受参数为字符串,结果与不设置全局标志的正则表达式为参数相同,只返回第一个匹配项,且具有index和input属性。

var string = 'cat,bat,sat,fat';
var matches = string.match('at');
console.log(matches,matches.index,matches.input);  // ['at'] 1 'cat,bat,sat,fat'
var matches = string.match('at');
console.log(matches,matches.index,matches.input);  // ['at'] 1 'cat,bat,sat,fat'

当不设置全局标志时,match()方法和exec()方法都包含捕获分组的信息;设置全局标志后,match()方法不包含捕获分组的信息。

var string = 'cat,bat,sat,fat';
var pattern = /(.)at/g;
var matches = string.match(pattern);
console.log(matches);  // ['cat', 'bat', 'sat', 'fat'] 
var exec = pattern.exec(string);
console.log(exec);  // ['cat','c'] 
 
var string = 'cat,bat,sat,fat';
var pattern = /(.)at/;
var matches = string.match(pattern);
console.log(matches);  // ['cat','c']  
var exec = pattern.exec(string);
console.log(exec);  // ['cat','c']

练习:两种方法找出字符串中所有的数字

        1. 用charAt()方法
	var str1 = 'j1h342jg24g234j 3g24j1';
	var array = [];
	var temp = '';
	for(var i = 0; i < str1.length; i++){
	    var value = parseInt(str1.charAt(i));//如果用Number()将无法排除空格
	    if(!isNaN(value)){
	        temp += str1.charAt(i);
	    }else{
	        if(temp != ''){
	            array.push(temp);
	            temp = '';    
	        }
	    }
	}
	if(temp != ''){
	    array.push(temp);
	    temp = '';    
	}
	console.log(array);  // ["1", "342", "24", "234", "3", "24", "1"]
 
	2. 用match()方法
	var str1 = 'j1h342jg24g234j 3g24j1';
	array = str1.match(/\d+/g);
	console.log(array);  // ["1", "342", "24", "234", "3", "24", "1"]

search()

search()方法接受一个正则或字符串的参数,返回匹配的内容在字符串中首次出现的位置,类似于不能设置起始位置的indexOf,找不到返回-1。
search()方法不执行全局匹配,忽略全局标志g,也会忽略RegExp对象的lastIndex属性,总是从字符串的开始位置开始搜索。

'x'.search(/y/);  // -1
 
var string = 'cat,bat,sat,fat';
var pattern = /.at/;
var pos = string.search(pattern);
console.log(pos);  // 0
 
var string = 'cat,bat,sat,fat';
var pattern = /.at/g;
var pos = string.search(pattern);
console.log(pos);  // 0
 
var string = 'cat,bat,sat,fat';
var pattern = 'at';
var pos = string.search(pattern);
console.log(pos);  // 1

练习:找出匹配的所有位置

function fnAllSearch(str,pattern){
    var pos = str.search(pattern); 
    var length = str.match(pattern)[0].length;
    var index = pos+length;
    var result = [];
    var last = index;
    result.push(pos);
    while(true){
        str = str.substr(index);                    
        pos = str.search(pattern);
        if(pos === -1){
            break;
        }
        length = str.match(pattern)[0].length;
        index = pos+length;
        result.push(last+pos);
        last += index;    
    }
    return result;
}    
console.log(fnAllSearch('cat23fbat246565sa3dftf44at',/\d+/));  // [3,9,17,22]

replace()

replace()方法用于替换一个或多个子字符串。它接收两个参数:第一个是正则表达式或字符串,表示待查找的内容;第二个是字符串或函数,表示替换内容。返回替换后的字符串。

字符串替换,只能替换第一个子字符串

var string = 'cat,bat,sat,fat';
var result = string.replace('at','ond');
console.log(result);  // 'cond,bat,sat,fat'

不设置全局标志g,也只能替换第一个子字符串

var string = 'cat,bat,sat,fat';
var result = string.replace(/at/,'ond');
console.log(result);  // 'cond,bat,sat,fat'

设置全局标志g,替换所有匹配的子字符串

var string = 'cat,bat,sat,fat';
var result = string.replace(/at/g,'ond');
console.log(result);  // 'cond,bond,sond,fond'

  • 与match()和seartch()方法相比,replace()方法更为强大,它可以在第二个参数中通过短属性名来使用某些正则表达式的静态属性。
短属性名         说明
$&              最近一次的匹配项
$`              匹配项之前的文本
$'              匹配项之后的文本
$1,$2...        表示第N个匹配捕获组
 
var string = 'cat-bat-sat-fat';
console.log(string.replace(/(.)(at)/g,'$&'));//'cat-bat-sat-fat'
console.log(string.replace(/(.)(at)/g,'$`'));//'-cat--cat-bat--cat-bat-sat-'
console.log(string.replace(/(.)(at)/g,"$'"));//'-bat-sat-fat--sat-fat--fat-'
console.log(string.replace(/(.)(at)/g,'$1'));//'c-b-s-f'
console.log(string.replace(/(.)(at)/g,'$2'));//'at-at-at-at'		
 
var string = '2016-06-24';
console.log(string.replace(/(\d{4})-(\d{2})-(\d{2})/g,'$2/$3/$1'));  // '06/24/2016'
  • replace()方法的第二个参数可以是函数,这样文本的处理更加灵活。如果在只有一个匹配项的情况下,该方法会向这个函数传递3个参数:模式的匹配项、模式匹配项在字符串中的位置、原始字符串。
var string = 'cat,bat,sat,fat';
var index = 0;
var matchArray = [];
var posArray = [];
var text = '';
var result = string.replace(/at/g,function(match,pos,originalText){
    matchArray.push(match);
    posArray.push(pos);
    text = originalText;
    index++;
    if(index % 2){
        return 'wow';
    }else{
        return '0';
    }
});
console.log(matchArray);  // ["at", "at", "at", "at"]
console.log(posArray);  // [1, 5, 9, 13]
console.log(text);  // 'cat,bat,sat,fat'
console.log(result);  // 'cwow,b0,swow,f0'
  • 如果正则表达式定义多个捕获组,则该方法传递给函数的参数依次是模式的匹配项、第一个捕获组的匹配项、第二个捕获组的匹配项……第N个捕获组的匹配项,但最后两个参数仍然分别是模式的匹配项在字符串中的位置和原始字符串,这个函数返回一个字符串。
var string = 'cat,bat,sat,fat';
var index = 0;
var matchArray = [];
var m1Array = [];
var posArray = [];
var text = '';
var result = string.replace(/(.)at/g,function(match,m1,pos,originalText){
    matchArray.push(match);
    m1Array.push(m1);
    posArray.push(pos);
    text = originalText;
    return m1 + 'ta';
});
console.log(matchArray);  // ["cat", "bat", "sat", "fat"]
console.log(m1Array);  // ['c','b','s','f']
console.log(posArray);  // [1, 5, 9, 13]
console.log(text);  // 'cat,bat,sat,fat'
console.log(result);  // 'cta,bta,sta,fta'

  • 练习:首字母大写
var text = 'one two three';
var result = text.replace(/\b(\w+)\b/g,function(match,m1,pos,originalText){
    return m1.charAt(0).toUpperCase()+m1.substring(1); 
})
console.log(result);
  • 练习:HTML标签转义
function htmlEscape(text){
    return text.replace(/[<>"&]/g,function(match,pos,originalText){
        switch(match){
            case '<':
            return '<';
            case '>':
            return '>';
            case '&':
            return '&';
            case '\"':
            return '"';
        }
    });
}
console.log(htmlEscape('<p class=\"greeting\">Hello world!</p>'));
//<p class=" greeting">Hello world!</p>
console.log(htmlEscape('<p class="greeting">Hello world!</p>'));
//同上
  • 练习:日期格式化
var array = ['2015.7.28','2015-7-28','2015/7/28','2015.7-28','2015-7.28','2015/7---28'];
function formatDate(date){
    return date.replace(/(\d+)\D+(\d+)\D+(\d+)/,'$1年$2月$3日')
}
var result = [];
for(var i = 0 ; i < array.length; i++){
    result.push(formatDate(array[i]));
}
console.log(result);
// ["2015年7月28日", "2015年7月28日", "2015年7月28日", 
    "2015年7月28日", "2015年7月28日", "2015年7月28日"]
  • 练习:找出重复项最多的字符和个数
var str = 'aaaaabbbbbdddddaaaaaaaffffffffffffffffffgggggcccccce';
var pattern = /(\w)\1+/g;
var maxLength = 0;
var maxValue = '';
var result = str.replace(pattern,function(match,match1,pos,originalText){
    if(match.length > maxLength){
        maxLength = match.length;
        maxValue = match1;
    }
})
console.log(maxLength,maxValue);  // 18 "f"

split()

split()方法基于指定的分隔符将一个字符串分割成多个字符串,并将结果放在一个数组中,分隔符可以是字符串,也可以是一个RegExp。该方法可以接受第二个参数(可选)用于指定数组的大小,如果第二个参数为0-array.length范围内的值时按照指定参数输出,其他情况将所有结果都输出。若指定分隔符没有出现在字符串中,则以数组的形式返回原字符串的值。参数中的正则表达式是否使用全局标志g对结果没有影响。

var colorText = 'red,blue,green,yellow';
console.log(colorText.split(''));
// ["r", "e", "d", ",", "b", "l", "u", "e", ",", "g", "r", "e", "e", "n", ",", "y", "e", "l", "l", "o", "w"]
console.log(colorText.split(','));//["red", "blue", "green", "yellow"]
console.log(colorText.split(',',2));//["red", "blue"]
console.log(colorText.split(',',6));//["red", "blue", "green", "yellow"]
console.log(colorText.split('-'));//["red,blue,green,yellow"]
console.log(colorText.split(/\,/));//["red", "blue", "green", "yellow"]
console.log(colorText.split(/e/));//["r", "d,blu", ",gr", "", "n,y", "llow"]
console.log(colorText.split(/[^\,]+/));//将除去逗号以外的字符串变为分隔符["", ",", ",", ",", ""],
IE8-会识别为[",",",",","]