Javascript字符串检索的方法总结

字符串检索相关的操作总结

前言扩展: 正则

在javascirpt里面可以用两种方法创建一个正则对象

1、使用字面量 /pattern/

var reg= /^[0-9]$/;    
var reg= /ab+c/i;

2、使用构造函数 new (pattern[,flags])

第二个参数为可选, 包含属性 "g"、"i" 和 "m",分别用于指定全局匹配、区分大小写的匹配和多行匹配

修饰符| 描述
----|------|----
i| 执行对大小写不敏感的匹配(ignore case)
g| 执行全局匹配(查找所有匹配项而非在找到第一个匹配后停止)(global)
m| 执行多行匹配。也就是,^ 和 $ 可以匹配字符串中每一行的开始和结束(行是由 \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之前,如果第一个参数是正则表达式而不是字符串的时候,第二个参数必须省略,否则会跑出TypeError (“当从其他正则表达式进行构造时不支持标志”)异常
到了ECMA6,不再抛出错误。那此时第二个参数有没有用呢?我们来试一试

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

可以看到,当第一参数是正则表达式的时候,第二个参数还是可以正确使用的
(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方法来检测是否存在相关字符串,而且还可以很自由地掌控检测规则,例如目标字符串在多少位后出现,重复出现几次等等
实际上与这个表达式是等价的 (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出现一次之后跟着若干个数字

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)

在循环中反复地调用 exec() 方法是唯一一种获得全局模式的完整模式匹配信息的方法。

exec也是正则对象的一个方法,可检索字符串中指定的值,返回一个数组,其中存放匹配的结果。它的使用比test()或者支持正则的StringObject的方法更复杂

  • 如果未找到匹配,则返回值为 null

  • 如果不包括g标志,返回一个结果数组,此数组的第 0 个元素是与正则表达式相匹配的文本,第 1 个元素是与 RegExpObject 的第 1 个子表达式相匹配的文本(如果有的话),第 2 个元素是与 RegExpObject 的第 2 个子表达式相匹配的文本(如果有的话),即返回stringObject.match()相同的结果;

    除了数组元素和 length 属性之外,exec() 方法还返回两个属性。index 表示匹配结果在原字符串中的索引。input 属性则存放的是被检索的字符串 string。

  • 如果正则表达式包括g标志,返回一个数组,数组的内容是所有包含匹配的字符串。不是位置!不是位置!;它会在RegExp的lastIndex置顶的位置开始检索字符串,当exec()找到了一个与表达式匹配的文本后,在匹配后,会吧lastIndex改为匹配文本的最后一个字符的最后一个位置。That mean 我们可以通过反复调用exec()来便利字符串中的所有匹配文本,当exec()再找不到匹配的文本时,将返回null,并把lastIndex置为0;
    注意:它不会一次返回所有匹配的项,而是每次执行都从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标志,三次执行结果一样,不会改变lastIndex的值



3、search

stringObject.search(regexp)

用于检索字符串中指定的子字符串,或检索 与正则表达式相匹配的子字符串。返回第一个与regexp相匹配的子串的起始位置,如果要执行忽略大小写的检索,追加标志i

特性:对大小写敏感,且不执行全局匹配,忽略标志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标志,返回一个数组,数组的内容是所有包含匹配的字符串。注意!不是位置!不是位置!;
  • 如果不包括g标志,返回一个数组,内容是第一个匹配的字符串,即返回与Reg.exec(str)相同的结果;
    而且返回的数组拥有额外的一个input属性,该属性包含原始字符串,另外还有一个index属性,表示匹配结果在原字符串中的索引
  • 如果未找到匹配,则返回值为 null

参数是一个正则表达式对象,如果传入一个非正则表达式对象,会隐式使用New RegExp(obj)将其转换为正则表达式对象

var b='Markdown markdown markdown'; 
b.match(/markdown/ig) //["Markdown", "markdown", "markdown"]
b.match(/markdown/i)  //["Markdown"]
b.match('markdown') //["markdown"] 这里发生了一次隐式转换
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。该方法区分大小写

兼容性: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()类似,返回一个数组或null
str.search()返回第一次出现的位置,与indexOf类似
会更新lastIndex属性的有RegExp.test()以及RegExp.exec()

参考资料:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,204评论 0 4
  • 本章内容 使用对象 创建并操作数组 理解基本的 JavaScript 类型 使用基本类型和基本包装类型 引用类型的...
    闷油瓶小张阅读 674评论 0 0
  • '^'必须才开头开始匹配'$'必须在末尾结束匹配'|' 表示‘或’/ab|cd/匹配ab或者cd'.'表示点字符(...
    zjh111阅读 410评论 0 0
  • 假设用户需要在HTML 表单中填写姓名、地址、出生日期等。那么在将表单提交到服务器进一步处理前,JavaScrip...
    胖先森阅读 349评论 0 2
  • 这是年轻创始人的成长过程,那个时刻我才认清到自己,才把光环剥离掉,重新认识什么才是真正的创业。 姚欣先生创业...
    朱习培阅读 474评论 0 0