[1]定義:正則又叫規則或模式,是一個強大的字符串匹配工具,在javascript中是一個對象
[2]特性:
[2.1]貪婪性,匹配最長的
[2.2]懶惰性,不設置/g,則只匹配第1個
[3]兩種寫法:
[3.1]perl寫法(使用字面量形式): var expression = /pattern/flags;
e.g. var pattern = /a/i;//匹配字符串中所有'a'的實例
[3.1.1]三個標志flags
[a]g:表示全局模式(global)
[b]i:表示不區分大小寫(ignoreCase)
[c]m:表示多行模式(multiline)
[3.2]js寫法(使用RegExp構造函數):兩個參數:要匹配的字符串模式、標志字符串(可選)
e.g. var pattern = new RegExp('[bc]at','i');
[注意]RegExp構造函數的兩個參數都是字符串
[3.3]構造函數與字面量的區別
[注意]可以使用字面量形式定義的任何表達式,都可以使用構造函數來定義
[3.3.1]字面量寫法不支持變量,只能用構造函數的形式來寫
[tips]獲取class元素(因為classname是變量,只能使用構造函數的形式)
function getByClass(obj,classname){ var elements = obj.getElementsByTagName('*'); var result = []; var pattern = new RegExp( '^|\\s'+ classname + '\\s|$'); for(var i = 0; i < elements.length; i++){ if(pattern.test(elements[i].className)){ result.push(elements[i]); } } }
[3.3.2]在ECMAScript3中,正則表達式字面量始終會共享同一個RegExp實例,而使用構造函數創建的每一個新RegExp實例都是一個新實例
var re = null, i; for(i = 0; i < 10; i++){ re = /cat/g; re.test('catastrophe'); } for(i = 0; i < 10; i++){ re = new RegExp('cat','g'); re.test('catastrophe'); }
[3.3.3]ECMAScript5中規定,使用正則表達式字面量必須像直接調用RegExp構造函數一樣,每次都創建新的RegExp實例
[4]語法
[重要事項]正則表達式中不能出現多余空格
[4.0]元字符(14個):() [] {} \ ^ $ | ? * + .
[注意]元字符必須轉義,即用\ 加轉義字符,用new RegExp寫的正則必須雙重轉義
[4.1]轉義字符
[4.1.0].號代表除了換行符\n之外的任意字符
[4.1.1]\d 數字 \D 非數字
[4.1.2]\w 字母、數字、下劃線 \W 非字母、數字、下劃線
[注意]漢字不屬於\w
[4.1.3]\s 空格 \S 非空格
[4.1.4]\b 邊界符,\w的左側或右側不是\w,則會出現一個邊界符 \B非邊界符
[4.1.5]\1 表示和前面相同的一個字符
[tips]找出重復項最多的字符和個數
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"
[4.1.6](\w)(\d)\1\2 :\1代表\w當時所代表的值,\2代表\d當時所代表的值
[注意]正則表達式中的子項必須是用小括號括起來的,並且順序以小括號的前括號出現的順序為准
[4.1.7]\t 制表符
[4.1.8]\v 垂直制表符
[4.1.9]\uxxxx 查找以十六進制xxxx規定的Unicode字符
[注意1][\u4e00-\u9fa5]代表中文
[注意2]alert()和console.log()裡面的字符是系統轉義字符
[a]\r return 回車
[b]\n newline 換行
[c]\t table 制表符
[d]\b backspace 退格
[tips]alert裡的換行不能用<br>或<br\>,而應該用\n。alert裡面相當於是系統解析的,而不是浏覽器
e.g.alert('http://www.baidu.com\n\t你好')
[注意3]由於RegExp構造函數的參數是字符串,所以某些情況下,需要對字符進行雙重轉義。所有元字符必須雙重轉義,已經轉義過的字符也必須雙重轉義
//字面量模式 -> 等價的字符串 // /\[bc\]at/ "\\[bc\\]at" // /\.at/ "\\.at" // /name\/age/ "name\\/age" // /\d.\d{1,2}/ "\\d.\\d{1,2}" // /\w\\hello\\123/ "\\w\\\\hello\\\\123"
[4.2]量詞
[4.2.1]{n}:匹配n次
[4.2.2]{n,m}:匹配至少n次,最多m次
[4.2.3]{n,}:匹配至少n次
[4.2.4]?:相當於{0,1}
[4.2.5]*:相當於{0,}
[4.2.6]+:相當於{1,}
[4.3]位置符號
[4.3.1]^起始符號
[4.3.2]結束符號為美元符號
[4.3.3]?=肯定正向環視
[4.3.4]?!否定正向環視
[4.4]控制符號([]:候選 |:或 ^:非 -:到)
[4.4.1](red|blue|green) 查找任何指定的選項
[4.4.2][abc] 查找方括號之間的任何字符
[4.4.3][^abc] 查找任何不在方括號之間的字符
[4.4.4][0-9] 查找任何從0到9的數字
[4.4.5][a-z] 查找任何從小寫a到小寫z的字符
[4.4.6][A-Z] 查找任何從大寫A到大寫Z的字符
[4.4.7][A-z] 查找任何從大寫A到小寫z的字符
[4.4.8][adgk] 查找給定集合內的任何字符
[4.4.9][^adgk] 查找給定集合外的任何字符
[4.5]美元符號
//$$ $ //$& 匹配整個模式的子字符串(與RegExp.lastMatch的值相同) //$` 匹配子字符串之前的子字符串(與RegExp.leftContext的值相同) //$' 匹配子字符串之後的子字符串(與RegExp.rightContext的值相同) //$n 匹配第n個捕獲組子字符串,其中n等於0-9。$1表示匹配第一個捕獲組的子字符串(從第1個算起) //$nn 匹配第nn個捕獲組的子字符串,其中nn等於01-99
console.log('cat,bat,sat,fat'.replace(/(.a)(t)/g,'$0'))//$0,$0,$0,$0 console.log('cat,bat,sat,fat'.replace(/(.a)(t)/g,'$1'))//ca,ba,sa,fa console.log('cat,bat,sat,fat'.replace(/(.a)(t)/g,'$2'))//t,t,t,t console.log('cat,bat,sat,fat'.replace(/(.a)(t)/g,'$3'))//$3,$3,$3,$3 console.log('cat,bat,sat,fat'.replace(/(.a)(t)/g,'$$'))//$,$,$,$ console.log('cat,bat,sat,fat'.replace(/(.a)(t)/g,'$&'))//cat,bat,sat,fat console.log('cat,bat,sat,fat'.replace(/(.a)(t)/g,'$`'))//,cat,,cat,bat,,cat,bat,sat, console.log('cat,bat,sat,fat'.replace(/(.a)(t)/g,"$'"))//,bat,sat,fat,,sat,fat,,fat,
[5]實例屬性:通過實例屬性可以獲知一個正則表達式的各方面信息,但卻沒有多大用處,因為這些信息全都包含在模式聲明中
[5.1]global:布爾值,表示是否設置了g標志
[5.2]ignoreCase: 布爾值,表示是否設置了i標志
[5.3]lastIndex: 整數,表示開始搜索下一個匹配項的字符位置,從0算起
[5.4]multiline: 布爾值,表示是否設置了標志m
[5.5]source: 正則表達式的字符串表示,按照字面量形式而非傳入構造函數中的字符串模式返回
var pattern = new RegExp('\\[bc\\]at','i'); console.log(pattern.global);//false console.log(pattern.ignoreCase);//true console.log(pattern.multiline);//false console.log(pattern.lastIndex);//0 console.log(pattern.source);//'\[bc\]at'
[6]構造函數屬性(靜態屬性):適用於作用域中的所有正則表達式,並且基於所執行的最近一次正則表達式操作而變化。關於這些屬性的獨特之處在於可以通過兩種方式訪問它們,即長屬性名和短屬性名。短屬性名大都不是有效的ECMAScript標識符,所以必須通過方括號語法來訪問它們
[6.1]使用這些屬性,可以從exec()方法或text()方法執行的操作中提取出更具體的信息
//長屬性名 短屬性名 說明
//input $_ 最近一次要匹配的字符串
//lastMatch $& 最近一次的匹配項
//lastParen $+ 最近一次匹配的捕獲組
//leftContext $` input字符串中lastMatch之前的文本
//multiline $* 布爾值,表示是否所有表達式都使用多行模式
//rightContext $' input字符串中lastMarch之後的文本
[注意1]opera不支持短屬性名
[注意2]opera不支持input\lastMatch\lastParen\multiline
[注意3]IE不支持multiline
var text = 'this has been a short summer'; var pattern = /(.)hort/g; if(pattern.test(text)){ console.log(RegExp.input);//'this has been a short summer' console.log(RegExp.leftContext);//'this has been a ' console.log(RegExp.rightContext);//' summer' console.log(RegExp.lastMatch);//'short' console.log(RegExp.lastParen);//'s' console.log(RegExp.multiline);//false console.log(RegExp['$_']);//'this has been a short summer' console.log(RegExp['$`']);//'this has been a ' console.log(RegExp["$'"]);//' summer' console.log(RegExp['$&']);//'short' console.log(RegExp['$+']);//'s' console.log(RegExp['$*']);//false }
[6.2]還有多達9個用於存儲捕獲組的構造函數屬性
//RegExp.$1\RegExp.$2\RegExp.$3……到RegExp.$9分別用於存儲第一、第二……第九個匹配的捕獲組。在調用exec()或test()方法時,這些屬性會被自動填充
var text = 'this has been a short summer'; var pattern = /(..)or(.)/g; if(pattern.test(text)){ console.log(RegExp.$1);//sh console.log(RegExp.$2);//t }
[7]實例方法:
[7.1]exec():專門為捕獲組而設計,接受一個參數,即要應用模式的字符串。然後返回包含第一個匹配項信息的數組。在沒有匹配項的情況下返回null。返回的數組包含兩個額外的屬性:index和input。index表示匹配項在字符串的位置,input表示應用正則表達式的字符串。在數組中,第一項是與整個模式匹配的字符串,其他項是與模式中的捕獲組匹配的字符串,如果模式中沒有捕獲組,則該數組只包含一項
var text = 'mom and dad and baby and others'; var pattern = /mom( and dad( and baby)?)?/gi; var matches = pattern.exec(text); console.log(pattern,matches); //pattern.lastIndex:20 //matches[0]:'mom and dad and baby' //matches[1]:' and dad and baby' //matches[2]:' and baby' //matches.index:0 //matches.input:'mom and dad and baby and others'
[注意1]對於exec()方法而言,即使在模式中設置了全局標志(g),它每次也只會返回一個匹配項
[注意2]在不設置全局標志的情況下,在同一個字符串上多次調用exec(),將始終返回第一個匹配項的信息
[注意3]在設置全局標志的情況下,每次調用exec()都會在字符串中繼續查找新匹配項
[注意4]IE8-的js實現在lastIndex屬性上存在偏差,即使在非全局模式下,lastIndex屬性每次也會變化
var text = 'cat,bat,sat,fat'; var pattern1 = /.at/; var matches = pattern1.exec(text); console.log(pattern1,matches); //pattern1.lastIndex:0 //matches[0]:'cat' //matches.index:0 //matches.input:'cat,bat,sat,fat' matches = pattern1.exec(text); console.log(pattern1,matches); //pattern1.lastIndex:0 //matches[0]:'cat' //matches.index:0 //matches.input:'cat,bat,sat,fat'
var text = 'cat,bat,sat,fat'; var pattern2 = /.at/g; var matches = pattern2.exec(text); console.log(pattern2,matches); //pattern2.lastIndex:3 //matches[0]:'cat' //matches.index:0 //matches.input:'cat,bat,sat,fat' matches = pattern2.exec(text); console.log(pattern2,matches); //pattern2.lastIndex:7 //matches[0]:'bat' //matches.index:4 //matches.input:'cat,bat,sat,fat'
[tips]用exec()方法找出匹配的所有位置和所有值
var string = 'j1h342jg24g234j 3g24j1'; var pattern = /\d/g; var valueArray = [];//值 var indexArray = [];//位置 var temp = pattern.exec(string); while(temp != null){ valueArray.push(temp[0]); indexArray.push(temp.index); temp = pattern.exec(string); } console.log(valueArray,indexArray);
[7.2]test():接受一個字符串參數,在模式與該參數匹配的情況下返回true,否則返回false
[注意]常用於只想知道目標字符串與某個模式是否匹配,但不需要知道其文本內容的情況,經常用在if語句中
var text = '000-00-000'; var pattern = /\d{3}-\d{2}-\d{4}/; if(pattern.test(text)){ console.log('The pattern was matched'); }
[8]模式匹配方法
[8.1]match():只接受一個參數,正則或字符串,把匹配的內容保存到一個數組中返回
[注意]加上全局標記時,match()方法返回值中沒有index和input屬性
[a]不加/g
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'
[b]加/g
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
[c]字符串
var string = 'cat,bat,sat,fat'; var pattern = 'at'; var matches = string.match(pattern); console.log(matches,matches.index,matches.input);//['at'] 1 'cat,bat,sat,fat'
[8.2]search():只接受一個參數,正則或字符串,返回匹配的內容在字符串中首次出現的位置,類似於不能設置起始位置的indexOf,找不到返回-1
[a]正則(加/g和不加/g效果一樣)
var string = 'cat,bat,sat,fat'; var pattern = /.at/; var pos = string.search(pattern); console.log(pos);//0
[b]字符串
var string = 'cat,bat,sat,fat'; var pattern = 'at'; var pos = string.search(pattern); console.log(pos);//1
[tips]找出匹配的所有位置
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]
[8.3]replace():接收兩個參數:第一個參數為正則表達式或字符串(待查找的內容)、第二個參數為字符串或函數(替換的內容)
[a]字符串替換
var string = 'cat,bat,sat,fat'; var result = string.replace('at','ond'); console.log(result);//'cond,bat,sat,fat'
[b]正則無/g替換
var string = 'cat,bat,sat,fat'; var result = string.replace(/at/,'ond'); console.log(result);//'cond,bat,sat,fat'
[c]正則有/g替換
var string = 'cat,bat,sat,fat'; var result = string.replace(/at/g,'ond'); console.log(result);//'cond,bond,sond,fond'
[d]函數替換:在只有一個匹配項(即與模式匹配的字符串的情況下,會向這個函數傳遞3個參數:模式的匹配項、模式匹配項在字符串中的位置、原始字符串。在正則表達式定義了多個捕獲組的情況下,傳遞給函數的參數依次是模式的匹配項、第一個捕獲組的匹配項、第二個捕獲組的匹配項……第N個捕獲組的匹配項,但最後兩個參數仍然分別是模式的匹配項在字符串中的位置和原始字符串,這個函數返回一個字符串。
[tips]防止跨站腳本攻擊xss(css)
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>')); //同上
[9]繼承的方法:都返回正則表達式字面量,與創建正則表達式的方式無關。要注意的是toString()和toLocaleString()返回的正則表達式的字符串表示,而valueOf返回的是正則表達式對象本身
[9.1]toString()
[9.2]toLocaleString()
[9.3]valueOf()
var pattern = new RegExp('\\[bc\\]at','gi'); console.log(pattern.toString()); // '/\[bc\]at/gi' console.log(pattern.toLocaleString()); // '/\[bc\]at/gi' console.log(pattern.valueOf()); // /\[bc\]at/gi
[10]局限性:下列為ECMAScript正則表達式不支持的特性
[10.1]匹配字符串開始的結尾的\A和\Z錨(但支持以^和$來匹配字符串的開始的結尾)
[10.2]向後查找(但支持向前查找)
[10.3]並集和交集類
[10.4]原子組
[10.5]Unicode支持(單個字符除外)
[10.6]命名的捕獲組(但支持編號的捕獲組)
[10.7]s(single單行)和x(free-spacing無間隔)匹配模式
[10.8]條件匹配
[10.9]正則表達式注釋
[11]常見實例
[11.1]兩種方法找出字符串中所有的數字
[11.1.1]用傳統字符串操作
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);
[11.1.2]用正則表達式完成
var str1 = 'j1h342jg24g234j 3g24j1'; array = str1.match(/\d+/g); console.log(array);
[11.2]敏感詞過濾(replace回調函數的應用)
var string = 'FLG是邪教'; var pattern = /FLG|邪教/g; var result = string.replace(pattern,function($0){ var s = ''; for(var i = 0; i < $0.length; i++){ s+= '*'; } return s; }) console.log(result);
[11.3]日期格式化
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);
[11.4]獲取網頁中的文本內容
var str = '<p>refds</p><p>fasdf</p>' var pattern = /<[^<>]+>/g; console.log(str.replace(pattern,''));
[11.5]去除首尾空格的trim()兼容寫法
var string = ' my name is littlematch '; console.log(string.replace(/^\s+|\s+$/,''));
希望以上關於javascript中正則表達式的描述,能夠對大家有所幫助。