// String#split() 'hello'.split(); // ["hello"] 'hello'.split(''); // ["h", "e", "l", "l", "o"] 'hello'.split('', 3); // ["h", "e", "l"] // 指定一个非空字符串 var source = 'hello world'; var result = source.split(' '); // ["hello", "world"] // 或者使用正则表达式 var result = source.split(/\s/); // ["hello", "world"] 如果separtor是一个正则表达式,并且正则中包含捕获组,则捕获组也会出现在结果数组中: // String#split() 正则捕获组 var source = 'matchandsplit'; var result = source.split('and'); // ["match", "split"] var result = source.split(/and/); // ["match", "split"] // 正则中含捕获组 var result = source.split(/(and)/); // ["match", "and", "split"]
最后来介绍一下String#replace()方法,它会同时执行查找和替换两个操作。
从上面的函数签名来看,该方法会接受两个参数:第一个参数可以是一个正则表达式,也可以是一个字符串,它们都表示将要匹配的子串;第二个参数可以指定一个字符串或是一个函数,如果指定一个字符串,表示这个字符串将会替换掉已匹配到的子串,如果指定一个函数,则函数的返回值会替换掉已匹配的子串。
String#replace()方法最终会返回一个新的已经过替换的字符串。下面分别演示了replace方法的使用:
// String#replace() var source = 'matchandsplitandreplace'; var result = source.replace('and', '-'); // "match-splitandreplace" // 或者 var result = source.replace(/and/, function() { return '-'; }); // "match-splitandreplace"
从上面的代码中可以看到,'and'被替换成了'-',但我们同时也注意到,只有第一个'and'被替换了,后面的并没有被处理。这里我们就需要了解,String#replace()方法只对第一次出现的匹配串进行替换,如果我们需要全局替换,需要将第一个参数指定为正则表达式,并追加全局g修饰符,就像下面这样:
// String#replace() 全局替换 var source = 'matchandsplitandreplace'; var result = source.replace(/and/g, '-'); // "match-split-replace" var result = source.replace(/and/g, function() { return '-'; }); // "match-split-replace"
初学者看到上面的代码,可能会觉得疑惑,对于第二个参数,直接指定一个字符串也挺简单的嘛,我们为何要使用一个函数然后再返回一个值呢。我们看看下面的例子就知道了:
// String#replace() 替换函数的参数列表 var source = 'matchandsplitandreplace'; var result = source.replace(/(a(nd))/g, function(match, p1, p2, offset, string) { console.group('match:'); console.log(match, p1, p2, offset, string); console.groupEnd(); return '-'; }); // "match-split-replace"
上面代码中,第一个参数是正则表达式,其中包含了两个捕获组(and)和(nd),第二个参数指定一个匿名函数,其函数列表中有一些参数:match, p1, p2, offset, string,分别对应匹配到的子串、第一个捕获组、第二个捕获组、匹配子串在源字符串中的索引、源字符串,我们可以称这个匿名函数为“replacer”或“替换函数”,在替换函数的参数列表中,match、offset和string在每一次匹配时总是存在的,而中间的p1、p2等捕获组,String#replace()方法会根据实际匹配情况去填充,当然,我们还可以根据arguments获取到这些参数值。
下面是代码运行后的控制台打印结果:
现在来看,指定一个函数要比指定一个字符串功能强的多,每次匹配都能获取到这些有用的信息,我们可以对其进行一些操作处理,最后再返回一个值,作为要替换的新子串。所以推荐在调用String#replace()方法时,使用上面这种方式。
上面是String类与正则相关的常用方法,需要注意的是,String#search()和String#match()方法签名中参数均为正则对象,如果我们传递了其他类型的参数,会被隐式转换为正则对象,具体的步骤是先调用参数值的toString()方法得到字符串类型的值,然后调用new RegExp(val)得到正则对象:
// -> String#search(new RegExp(val.toString())) '123 123'.search(1); // 0 'true false'.search(true); // 0 '123 123'.search('\\s'); // 3 var o = { toString: function() { return '\\s'; } }; '123 123'.search(o); // 3 // -> String#match(new RegExp(val.toString())) '123 123'.match(1); // ["1"] 'true false'.match(true); // ["true"] '123 123'.match('\\s'); // [" "] var o = { toString: function() { return '1(23)'; } }; '123 123'.match(o); // "123", "23"]