在javascript中使用正則表達式

作者:烽行天下

String的replace方法(字符替換)

在JavaScript中,每一個字符串對象有一個replace()方法。這replace()方法可心使用一個正則表達式對象作為第一個參數,可以是一個靜態的字符串或一個函數作為第二個參數。當調用replace()方法時,傳入一個字符串,原字符串中所有與正則匹配的字符都會被替換成這個字符串:

// -- String.replace() -------------------------------------- //

// Create a test string.
var value = "Hey Tricia, how's it going?";

// The replace() method can take a static replacement string as
// the second argument. Replace the name Tricia with the name
// Joanna.
var newValue = value.replace(
    new RegExp( "\\bTricia\\b", "gi" ),
    "Joanna"
);

// Output the new string.
document.write( newValue );

這里,我們找到所有的"Tricia"并替換成"Joanna"。

當我們運行上面的代碼,我們可以得到這樣的結果:

Hey Joanna, how's it going?  
這里傳入的是一個靜態的字符串,但它可以具有一些動態的特性。通過匹配模式的捕獲組功能,替換字符串可以由多部分的匹配共同組成。在正則表達式模式下,每個捕獲組可以在替換字符串中使用$N來標記,在這里N是捕獲組在正則表達示中的索引位置。

// -- String.replace() -------------------------------------- //
 
// Create a test string.
var value = "Hey Tricia, how's it going?";
 
// The replace() method can take a static replacement string as
// the second argument. This static string can contain references
// to captured groups in the pattern. Replace the name Tricia
// with the name hottest Tricia.
var newValue = value.replace(
new RegExp( "\\b(Tricia)\\b", "gi" ),
"hottest $1"
);
 
// Output the new string.
document.write( newValue );

在這個示例中,我們用"hottest $1"來替換"Tricia"。由于$1指向第一個捕獲組匹配的值,運行這段代碼,我們可以得到這樣的結果:

Hey hottest Tricia, how's it going?
在這里你可以看到"hottest $1" 被替換成了"hottest Tricia".

String的replace方法(函數替換)
通過傳入上例中的字符串是一種很方便也節省時間的方法,但如果我們想要更多的干預替換的行為,我們可以傳入一個方法體來實現。這是一個我個人很喜歡同時也經常 使用的小技巧。每次匹配規則作用于源字符串時都會執行一次這個方法.源字符中被匹配的字符及每個捕獲組都會作為特有的參數傳入方法內。源字符中與正則匹配的部分會被這個方法的return值替換。

// -- String.replace() -------------------------------------- //
 
// Create a test string.
var value = "Hey Tricia, how's it going?";
 
// The replace() method can take a method as the second argument.
// In this case, the return value of the method is what is
// replaced into the string. The first argument passed to this
// method is the matched pattern; each subsequent argument is a
// captured group from the pattern.
var newValue = value.replace(
new RegExp( "\\b(\\w+)'(s)\\b", "gi" ),
 
// This method will handle the replacement. In this case,
// the $1 is the \\w+ and the $2 is the s.
function( $0, $1, $2){
// Replace in "is".
return( $1 + " is" );
}
);
 
// Output the new string.
document.write( newValue );

通過上例你可以看到所有減寫的is都會被替換成標準寫法,我們可以得到如下結果:

Hey Tricia, how is it going?

String的match方法(非全局匹配)

JavaScript中,我們還可以使用match方法來收集被匹配的值.match方法可以生成并返回一個源字符中所有與正則匹配的值的數組(譯者注:如果可以找到匹配)。

值得一說的是,在match方法里使用全局匹配標簽g與否會產生不行的行為效果。

當我們未傳入全局匹配的g標簽時,match方法會返回一個包含一個該正則完整匹配的字符及其后仍次的子分組匹配字符的數組

// -- String.match() ---------------------------------------- //
 
// Create a test string.
var value = "aabbccddee";
 
// Get the matches in the string. When this is run WITHOUT the
// global flag, it returns the entire match, and then each
// captured group as a subsequent match index.
var matches = value.match(
new RegExp(
"/(\w)(\1)+/i",
"i"
)
);
 
// Output the array of matches.
console.log( matches );

上例的目地是為了找到一個或多個有重復字母的字符串。在這里并沒有使用全局匹配g,該正則的語法解釋是 \w匹配字母,\1匹配第一個子分組,既(\w)。

我們可以得到這樣的結果。

aabbccddee,a,a

(譯者注,該文原先的正則使用了不分配分組,并且和下文的全局匹配無法統一,為了便于理解,譯者把該正則寫法統一了,以便下文中對全局匹配區分)

在這里,aabbccddee即是上文提到的"該正則完整匹配的字符",而"a","a"則是"其后仍次的子分組匹配字符"

注意: 當正則表達式沒有發現匹配, match會返回 null ,而不是空數組.  

String的match方法(全局匹配)

當我們傳入全局匹配的g標簽時,match方法會返回包含所有該正則匹配的字符串的數組而不會包含任何子分組的匹配

// -- String.match() ---------------------------------------- //
 
// Create a test string.
var value = "aabbccddee";
 
// Get the matches in the string. When this is run WITH the
// global flag, it returns a single pattern match in each of the
// array indexes (regardless of capturing).
var matches = value.match(/(\w)(\1)+/ig);
 
// Output the array of matches.
console.log( matches );

當我們執行上述代碼,我們可以得到:

aa,bb,cc,dd,ee

各位可以看到,每個(\w)(\1)+所匹配的字符串都會作為match方法返回的數組中的一個元素,這里不會再包含任何對子分組的匹配。

String的search方法

字符串search()方法和indexof()方法很類似,但使用正則表達式。

這個方法只需要傳入一個正則表達式,執行后返回第一個匹配的索引,或-1(如果沒有發現匹配)

// -- String.search() --------------------------------------- //
 
// Create a test string.
var value = "Kate, you are looking very hot!";
 
// Search for a value in the string. Returns index or -1.
console.log(value.search( new RegExp( "are", "i" ) ) +"
");

// Search for a value NOT in the string. Returns index or -1.
console.log(value.search( new RegExp( "fun", "i" ) ) +"
");

在上例中我們準備了一個能夠匹配源字符串的正則及一個無法匹配的正則,運行這段代碼,我們可以得到

10
-1
可以發現,are在源字符串的索引10位置,而fun無法被匹配上,返回-1

RegExp的test方法

正則表達式test()方法只會根據給定的源字符串是否能匹配正則表達式而返回true或false:

// -- RegExp.test() ----------------------------------------- //
 
// Create a test string.
var value = "Kate, you are looking very hot!";
 
// Create a testing pattern.
var pattern = new RegExp( "\\bhot\\b", "i" );
 
// Test to see if the given string matches the given expression.
// Return TRUE or FALSE.
console.log(pattern.test( value ));

當我們執行上面的代碼,可以得到:

true
可以看出,該正則能夠匹配給定的源字符串。有一點需要重點提示:test方法并不需要該正則完整的匹配源字符串才行。如果你需要正則能完整的匹配源字符串才返回true,那需要在正則的前后加上^和$標記.

RegExp的exec方法

exec方法允許我們收集收集被匹配的值;但是,和String的match方法不同的是exec方法允許我們更深入每一次正則匹配的過程。exec方法可以讓我們遍歷每一次正則匹配的子字符串。在每一次匹配的回調事件中,我們不但可以到得被匹配的字符串的值及其索引,還可以得到每個子分組的匹配結果。

// -- RegExp.exec() ----------------------------------------- //
 
// Create a test string.
var value = "aabbccddee";
 
// Create a pattern to find the doubled characters.
var pattern = new RegExp( "((\\w)\\2)", "gi" );
 
// Use exec() to keep looping over the string to find the
// matching patterns. NOTE: Since we are using a loop, you MUST
// use the global flag "g", otherwise, this will cause an
// infinite loop to occur.
while (matches = pattern.exec( value )){
 
console.log( matches + "
" );
 
}

執行上面的代碼,可以得到下面的結果:

aa,aa,a
bb,bb,b
cc,cc,c
dd,dd,d
ee,ee,e

上面的例子中,我們不但可以得到每個匹配的重復字符串,還可以通過子分組匹配到重復字符串中的每一個字符。

可以看出來,exec方法可以讓我們得到String的match的能力同時,還具有更深入String的replace方法的能力。與此同時,exec方法,還可以更有用處:看看它是如何更新RegExp實例的http://www.bennadel.com/blog/697-Javascript-Exec-Method-For-Regular-Expression-Matching.htm

這篇文章并不是想深入JavaScript中每個正則表達式的用法,只是做一個全面的介紹。就像我上文中提到,正則表達示是極好的,我只是想有一個更全面的了解。

本文由simon4545根據 Ben Nadel 的《Using Regular Expressions In Javascript (A General Overview)》所譯,整個譯文帶有我們自己的理解與思想,如果譯得不好或不對之處還請同行朋友指點。如需轉載此譯文,需注明英文出處:http://www.bennadel.com/blog/1742-Using-Regular-Expressions-In-Javascript-A-General-Overview-.htm,以及作者相關信息
——作者: Ben Nadel
——譯者:simon4545

四川时时彩在线投注