字符串檢索相關的操作總結
前言擴展: 正則
在javascirpt里面可以用兩種方法創(chuàng)建一個正則對象
1政模、使用字面量 /pattern/
var reg= /^[0-9]$/;
var reg= /ab+c/i;
2较锡、使用構造函數(shù) new (pattern[,flags])
第二個參數(shù)為可選, 包含屬性 "g"、"i" 和 "m",分別用于指定全局匹配管宵、區(qū)分大小寫的匹配和多行匹配
修飾符| 描述
----|------|----
i| 執(zhí)行對大小寫不敏感的匹配(ignore case)
g| 執(zhí)行全局匹配(查找所有匹配項而非在找到第一個匹配后停止)(global)
m| 執(zhí)行多行匹配。也就是,^ 和 $ 可以匹配字符串中每一行的開始和結束(行是由 \n 或 \r 分割的)箩朴,而不只是整個輸入字符串的最開始和最末尾處笛臣。(multiline)
注:正則的快速學習教程推薦
var reg= new RegExp('^abc{1}[0-9]*$','i'); 正則表達式運行時編譯
var reg= new RegExp('^abc{1}[0-9]*$');
var reg= new RegExp(/ab+c/,'i'); 直接使用正則表達式構造對象
var reg= new RegExp(/ab+c/i)
注:ECMA6之前,如果第一個參數(shù)是正則表達式而不是字符串的時候隧饼,第二個參數(shù)必須省略沈堡,否則會跑出TypeError (“當從其他正則表達式進行構造時不支持標志”)異常
到了ECMA6,不再拋出錯誤燕雁。那此時第二個參數(shù)有沒有用呢诞丽?我們來試一試
var reg= new RegExp(/^abc{1}[0-9]*$/,'i'); reg.test('Abc5');
//true 實際等同下一條
var reg= new RegExp(/^abc{1}[0-9]*$/i); reg.test('Abc5');
//true
var reg= new RegExp(/^abc{1}[0-9]*$/); reg.test('Abc5');
//false
可以看到,當?shù)谝粎?shù)是正則表達式的時候拐格,第二個參數(shù)還是可以正確使用的
(chrome v49.0.2623)
方法| 描述
----|------|----
compile| 編譯正則表達式
exec| 檢索字符串中指定的值僧免。返回找到的值,并確定其位置捏浊。
test| 檢索字符串中指定的值懂衩。返回 true 或 false。
注:正則的快速學習教程推薦http://deerchao.net/tutorials/regex/regex-1.htm
下面正式進入主題
1金踪、test
RegExpObject.test(string)
test() 方法是正則對象的一個方法浊洞,用于檢測一個字符串是否匹配某個模式,返回 true 或 false胡岔。
對法希,我們可以編寫相應的正則方法,然后使用Reg對象的test方法來檢測是否存在相關字符串靶瘸,而且還可以很自由地掌控檢測規(guī)則苫亦,例如目標字符串在多少位后出現(xiàn),重復出現(xiàn)幾次等等
實際上與這個表達式是等價的 (r.exec(s)!=null)
var reg= new RegExp(/^abc{1}[0-9]*$/); reg.test('abc5'); //true
var reg= new RegExp(/^abc{1}[0-9]*$/); reg.test('cccabc5'); // false
var reg= new RegExp(/^abc{1}[0-9]*$/i); reg.test('Abc5'); //true
var reg= new RegExp(/^abc{1}[0-9]*$/); reg.test('Abc5'); //false
//在開頭abc出現(xiàn)一次之后跟著若干個數(shù)字
test方法會更新lastIndex屬性
var strs='Markdown markdown markdown';
var reg=new RegExp(/markdown/g);
reg.test(strs);//true
console.log(reg.lastIndex)//17
reg.test(strs);//true
console.log(reg.lastIndex)//26
reg.test(strs);//false
console.log(reg.lastIndex)//0
2怨咪、exec
RegExpObject.exec(string)
在循環(huán)中反復地調用 exec() 方法是唯一一種獲得全局模式的完整模式匹配信息的方法屋剑。
exec也是正則對象的一個方法,可檢索字符串中指定的值诗眨,返回一個數(shù)組唉匾,其中存放匹配的結果。它的使用比test()或者支持正則的StringObject的方法更復雜
如果未找到匹配辽话,則返回值為 null
-
如果不包括g標志肄鸽,返回一個結果數(shù)組卫病,此數(shù)組的第 0 個元素是與正則表達式相匹配的文本油啤,第 1 個元素是與 RegExpObject 的第 1 個子表達式相匹配的文本(如果有的話),第 2 個元素是與 RegExpObject 的第 2 個子表達式相匹配的文本(如果有的話)蟀苛,即返回stringObject.match()相同的結果益咬;
除了數(shù)組元素和 length 屬性之外,exec() 方法還返回兩個屬性帜平。index 表示匹配結果在原字符串中的索引幽告。input 屬性則存放的是被檢索的字符串 string梅鹦。
如果正則表達式包括g標志,返回一個數(shù)組冗锁,數(shù)組的內容是所有包含匹配的字符串齐唆。不是位置!不是位置6澈印箍邮;它會在RegExp的lastIndex置頂?shù)奈恢瞄_始檢索字符串,當exec()找到了一個與表達式匹配的文本后叨叙,在匹配后锭弊,會吧lastIndex改為匹配文本的最后一個字符的最后一個位置。That mean 我們可以通過反復調用exec()來便利字符串中的所有匹配文本擂错,當exec()再找不到匹配的文本時味滞,將返回null,并把lastIndex置為0钮呀;
注意:它不會一次返回所有匹配的項剑鞍,而是每次執(zhí)行都從lastIndex開始找一個匹配項,就返回
var str="Jianshu markdown bu zhi chi table Markdown,markdown repeat";
var agi=new RegExp('markdown','gi')爽醋;
//var agi=new RegExp(/markdown/gi);
console.log(agi.exec(str)) console.log(ag.lastIndex)
console.log(agi.exec(str)) console.log(ag.lastIndex)
console.log(agi.exec(str)) console.log(ag.lastIndex)
//["markdown", index: 8, input: "Jianshu markdown bu zhi chi table Markdown , markdown repeat"]
//16
//["Markdown", index: 34, input: "Jianshu markdown bu zhi chi table Markdown , markdown repeat"]
//42
//["markdown", index: 45, input: "Jianshu markdown bu zhi chi table Markdown , markdown repeat"]
//53
//null
//0
//global模式下每次返回一個匹配的值,改變lastIndex的值
var ai=new RegExp('markdown','i');
//var ai=new RegExp(/markdown/i);
console.log(ai.exec(str));console.log(ai.lastIndex)
console.log(ai.exec(str));console.log(ai.lastIndex)
console.log(ai.exec(str));
//["markdown", index: 8, input: "Jianshu markdown bu zhi chi table Markdown , markdown repeat"]
//0
//["markdown", index: 8, input: "Jianshu markdown bu zhi chi table Markdown , markdown repeat"]
//0
//["markdown", index: 8, input: "Jianshu markdown bu zhi chi table Markdown , markdown repeat"]
//沒有global標志攒暇,三次執(zhí)行結果一樣,不會改變lastIndex的值
3子房、search
stringObject.search(regexp)
用于檢索字符串中指定的子字符串形用,或檢索 與正則表達式相匹配的子字符串。返回第一個與regexp相匹配的子串的起始位置,如果要執(zhí)行忽略大小寫的檢索证杭,追加標志i
特性:對大小寫敏感田度,且不執(zhí)行全局匹配,忽略標志g解愤,也忽略lastIndex屬性镇饺,總是從字符串的開始進行檢索
var a="Jianshu markdown bu zhi chi table Markdown";
a.search('jianshu'); //-1
a.search('Jianshu'); //0
a.search('markdown'); //8
a.search(/\bmarkdown\b/) ; //8
a.search(/JIanShu/i) //0 使用search做忽略大小寫的匹配呢,就是在后面加i
4送讲、match
stringObject.match(regexp)
當字符串匹配到正則表達式的時候奸笤,match()會提取匹配項
- 如果正則表達式包括g標志,返回一個數(shù)組哼鬓,數(shù)組的內容是所有包含匹配的字符串监右。注意!不是位置异希!不是位置=『小;
- 如果不包括g標志,返回一個數(shù)組扣癣,內容是第一個匹配的字符串惰帽,即返回與Reg.exec(str)相同的結果;
而且返回的數(shù)組擁有額外的一個input屬性父虑,該屬性包含原始字符串该酗,另外還有一個index屬性,表示匹配結果在原字符串中的索引 - 如果未找到匹配士嚎,則返回值為 null
參數(shù)是一個正則表達式對象垂涯,如果傳入一個非正則表達式對象,會隱式使用New RegExp(obj)將其轉換為正則表達式對象
var b='Markdown markdown markdown';
b.match(/markdown/ig) //["Markdown", "markdown", "markdown"]
b.match(/markdown/i) //["Markdown"]
b.match('markdown') //["markdown"] 這里發(fā)生了一次隱式轉換
b.match('markdown/i') //null 因為是直接吧markdown/i整個字符串進行RegExp構建的
var c=b.match(/markdown/)
console.log(c); //["markdown", index: 9, input: "Markdown markdown markdown"]
//嘗試設置lastIndex改變匹配起始處
var b='Markdown markdown markdown';
var temp=new RegExp(/markdown/);
temp.lastIndex=18;
var c=b.match(temp);
console.log(c)
//["markdown", index: 9, input: "Markdown markdown markdown"]
//似乎沒有用
在w3c的頁面找到了一個說明
重要事項:不具有標志 g 和不表示全局模式的 RegExp 對象不能使用 lastIndex 屬性航邢。
好耕赘,那在全局模式再試一下
var b='Markdown markdown markdown';
var temp=new RegExp(/markdown/g);
temp.lastIndex=18;
var c=b.match(temp);
console.log(c)
//["markdown", "markdown"]
//依然沒有用
5、includes
includes() 方法用于 判斷一個字符串是否被包含在另一個字符串中膳殷,如果是返回 true操骡,否則返回 false。該方法區(qū)分大小寫
兼容性:ECMA6赚窃,chrome 41+册招、firefox 40+,safari 9+勒极;ie全系不支持
stringObject.includes(searchString [, position])
searchString 將要搜尋的子字符串是掰。 position
可選。從當前字符串的哪個索引位置開始搜尋子字符串辱匿;默認為0键痛。
var str = 'To be, or not to be, that is the question.';
console.log(str.includes('To be')); // true
console.log(str.includes('question')); // true
console.log(str.includes('nonexistent')); // false
console.log(str.includes('To be', 1)); // false
console.log(str.includes('TO BE')); // false
Polyfill:
if (!String.prototype.includes) {
String.prototype.includes = function(search, start) {
'use strict';
if (typeof start !== 'number') {
start = 0;
}
if (start + search.length > this.length) {
return false;
} else {
return this.indexOf(search, start) !== -1;
}
};
}
總結一下
str.includes()跟RegExp.test()類似,返回一個布爾值
str.match()跟RegExp.exec()類似,返回一個數(shù)組或null
str.search()返回第一次出現(xiàn)的位置匾七,與indexOf類似
會更新lastIndex屬性的有RegExp.test()以及RegExp.exec()
參考資料:
- https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/includes
- https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp
-
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp
http://www.w3school.com.cn/jsref/jsref_obj_regexp.asp