【javascript雜談】你所不知道的replace函數

前言

最近在作面試題的時候總會用到這個函數,這個函數老是和正則表達式聯繫到一塊兒,而且效果非常不錯,總能很簡單出色的完成字符串的實際問題,你們確定都會使用這個函數,像我同樣的初學者可能對這個函數的瞭解仍是不夠深的,今天就總結一下,瞭解一下,再作幾道網上的題目練練手,給將要面試的同窗打打氣。javascript

介紹

使用一個替換值替換掉一個替換模式在原字符串中一個或全部的匹配項,並返回替換後的字符串,這個替換模式能夠是字符串或者正則表達式,替換值能夠是一個字符串或者是一個函數java

後面的大的黑體就是咱們開始沒有注意到的。面試

語法

newstring = str.replace(regexp|substr, newSubStr|function[,  flags]);這是官方的解釋不是很清楚,一會好好解釋下。正則表達式

參數

regexp
一個 REGEXP(正則)對象,該正則所匹配的內容會被第二個參數的返回值替換掉。
substr
替換掉的一個字符串
newSubStr
替換掉第一個參數在原字符串中的匹配部分,該字符串中能夠內插一些特殊的變量名。對於正則replace約定了一個特殊標記符$:
  1. $n (n:1-99) : 表示從左到右正則子表達式所匹配的文本。各個分組匹配的字符串
  2. $&:表示與正則表達式匹配的全文本。
  3. $`(`:切換技能鍵):表示匹配字符串的左邊文本。
  4. $’(‘:單引號):表示匹配字符串的右邊文本。
  5. $$:表示$轉移。
function
是一個函數,能夠有返回值,也能夠無返回值。參數的個數不固定,參數挺麻煩的,咱主要就是說這個函數,
  1. 第一個參數爲每次匹配的全文本($&),就是整個匹配的字符串
  2. 中間參數爲子表達式匹配字符串,個數不限.( $n (n:1-99)),有分組的時候
  3. 倒數第二個參數爲匹配文本字符串的匹配下標位置。
  4. 最後一個參數表示字符串自己。

這個函數在執行replace時執行,若是有返回值,返回值用來替換replace的第一個參數。chrome

flags
就是正則表達式那些特殊的標誌,無關緊要的,當第一個參數是字符串的時候使用。
g   全局替換
i   忽略大小寫
m   多行模式
y      sticky

注意:replace函數並不改變原來的字符串,而是返回來一個新的字符串。express

好多例子

說估計你們也是不明白,如今我把全部的狀況弄個例子,幫助你們理解:瀏覽器

例子1:函數

//replace(str,str);
var
str = "I am hainan"; var newStr = str.replace("hainan","Allenxing"); console.log(newStr);//I am Allenxing console.log(str);//I am hainan

例子2:spa

// replace(str,str,flag)
var str = "I am hainan hainan";
var newStr = str.replace("hainan","Allenxing","gi");
console.log(newStr);//I am Allenxing Allenxing(FireFox下)  I am Allenxing Allenxing(chrome IE下)  
console.log(str);//I am hainan hainan

這種各狀況個瀏覽器支持的很差,建議使用帶標記的正則表達式,而不是使用字符串的這種標記,官方這樣說code

A string specifying a combination of regular expression flags. The use of the flags parameter in the String.replace method is non-standard, use a RegExp object with the corresponding flags.

例子3:

// replace(RegExp,str)
var str = "I am hainan hainan";
var newStr1 = str.replace(/hainan/,"Allenxing");
console.log(newStr1);//I am Allenxing hainan 

var newStr2 = str.replace(/hainan/g,"Allenxing");
console.log(newStr2);//I am Allenxing Allenxing

var str1 = "I am hainan Hainan";
console.log(str1.replace(/hainan/ig,"Allenxing"));//I am Allenxing Allenxing 
console.log(str1.replace(/hainan/g,"Allenxing"));//I am Allenxing Hainan

例子4:$1是匹配第一個分組的內容,$2是匹配第一個分組的內容......

//replace(RegExp,'特殊標記')
var str = "I am hainan hainan";
console.log( str.replace(/(hainan)/,"*$1*") );//I am *hainan* hainan 

解釋一下:/(hainan)/ 匹配的是第一個hainan,咱們使用"*$1*"的意思就是"*hainan*",用它替換hainan,是第二個參數替換前面的總體。

例子5:

//replace(RegExp,'特殊標記')
var str = "I am hainan Allenxing";
console.log( str.replace(/(hainan)\s*(Allenxing)/g,"$2 $1") );//I am Allenxing hainan 

例子6:

//replace(RegExp,'特殊標記')
var str = "I am hainan Allenxing";
console.log( str.replace(/(hainan)\s*(?:Allenxing)/g,"$2 $1") );//I am $2 hainan 

解釋:(?:)是非捕獲分組,匹配內容可是不捕獲,也就是$2中如今沒有內容,那麼就按照$2是個字符串輸出。

例子7:$&表明正則匹配的總體

//replace(RegExp,'特殊標記')
var str = "hainan";
console.log( str.replace(/(h)ainan/g,"$& starts with $1") );//hainan starts with h 

例子8:$`表示匹配字符串的左邊文本,$’(‘:單引號)表示匹配字符串的右邊文本。

//replace(RegExp,"特殊標記")
var str = "javascript";
console.log(str.replace(/java/,"$&$' is "));//javascript is script 

console.log(str.replace(/script/,"$& is not $`"));//avascript is not java 

參數是function 

咱們前面簡單介紹了參數function,咱們寫個例子看看這個函數的參數都有什麼東西,

//replace(RegExp,function)
var str = "I am hainan Allenxing";
console.log( str.replace(/(hainan)\s*(Allenxing)/g,function(){
  console.(arguments);//看看參數的樣子
}) );

看截圖吧,清楚些

這樣能夠清楚的看出來,函數的第一個參數是正則匹配的全文本(hainan Allenxing),第二個是第一個分組匹配的文本(hainan),第三個是第二個分組匹配的文本(Allenxing),第四個參數是匹配文本字符串的匹配下標位置,第五個參數是整個輸入的字符串(I am hainan Allenxing)。後面的幾個參數的位置肯能會改變,由於再有分組的話,中間分組的參數個數會增長。

再看下結果,I am undefined  ,因爲咱們function沒有明確返回值,因此就是undefined,用undefined替換了正則匹配的全文本。

還有一個問題就是,匹配的時候這個function要執行幾回呢?每一次裏面的參數的值會發生什麼變化呢?看例子

//replace(RegExp,function)
var str = "I am hainan hainan";
console.log( str.replace(/(hainan)/g,function(){
  console.log(arguments);
}) );

結果就是這樣

這個能夠看出,function執行了兩遍,就是由於正則(/(hainan)/g)匹配了兩遍,咱們能夠再驗證一下,

//replace(RegExp,function)
var str = "I am hainan hainan";
console.log( str.replace(/(hainan)/,function(){
  console.log(arguments);
}) );

確實是這樣吧,裏面的參數時每一次匹配的結果。而咱們每次替換的值就是第一個參數的值,由於第一的參數就是正則匹配的全文本嘛。

用function解決幾個前面的例子吧

先看例子5那個

//replace(RegExp,'特殊標記')
var str = "I am hainan Allenxing";
console.log(str.replace(/(hainan)\s*(Allenxing)/g,function(arg0,arg1,arg2){
     return arg2 + " " + arg1;     
}));
//I am Allenxing hainan

再看例子8

var str = "javascript";
console.log(str.replace(/java(script)/g,function(arg0,arg1){
   return arg0 +" is " + arg1;
}))

都是差很少的,只是用function作參數時,咱們不能使用原來的正則表達式來獲得匹配字符的左右的字符,須要修改正則表達式。

弄一個實際的例子,查找字符串中出現最多的字符和個數?   例如:sdjksfssscfssdd  -> 字符最多的是s,出現了7次。用replace函數解決。

var str = "sdjksfssscfssdd";
str = str.split("").sort().join("");
var count = 0;
var val;
str.replace(/(\w)\1*/g,function(arg0,arg1){
    if(arg0.length > count){
      count = arg0.length;
      val = arg1;
    }
});    
console.log(val+" 出現了"+count+" 次");

小結

replace函數就總結到這,其實它能作好多事情,其實主要是正則表達式的功勞,正則表達式這裏就不詳細說了,園子裏好多牛人都總結過,你們能夠找找看看,想要面試的同窗好好準備吧。

相關文章
相關標籤/搜索