正则表达式

推荐的网址

MDN中JS中的正则表达式后盾人js的正则表达式文档

正则表达式

使用单个字符串来描述、匹配一系列符合某个句法规则的字符串搜索模式。搜索模式可用于文本搜索文本替换

语法

对象创建

var re = new RegExp(pattern[, flags])
使用场景
  • 如果正则表达式保持不变时,使用此方法可以获得更好的性能。
注意事项
  • pattern由引号包围
  • pattern的字符串中的转义字符
    例如:\w -> "\\w"

字面量创建

var re = /pattern/[flags];
使用场景
  • 如果正则表达式会改变时或者从用户输入等来源动态地产生,使用构造函数创建正则表达式。
注意事项
  • 斜杠包围

编写正则表达式的模式[pattern和flags]

简单模式

简单模式由想要直接找到的字符构成 或 简单和特殊字符的组合。

  • 注意事项
    使用的情况比较窄、不通用

特殊字符

匹配一个不确定的字符串的时候,可以在模式中使用特殊字符。

  • 选择符
    |表示选择符,即左右两侧匹配一个即可。
let reg = /ab|ac/;
console.log("abcsdfac".match(reg))

// 测试结果
["ab", index: 0, input: "abcsdfac", groups: undefined]
  • 字符边界
边界符 说明
^ 匹配输入的开始
$ 匹配输入的结束
  • 元字符
元字符 说明 示例
\d 匹配一个数字 [0-9]
\D 匹配一个非数字字符 [^0-9]
\w 匹配一个单字字符(字母、数字或者下划线) [A-Za-z0-9_]
\W 匹配一个非单字字符 [^A-Za-z0-9_]
\s 匹配一个空白字符,包括空格、制表符、换页符和换行符 [\t\v\r\n\f]
\S 匹配一个非空白字符 [^\t\v\r\n\f]
. 匹配除换行符之外的任何单个字符

表示所有字符:
[\s\S]或[\d\D]

  • 原子表
原子表 说明 例子
[xyz] 一个字符集合。匹配方括号中的任意一个字符 [a-z]
[^xyz] 一个反向字符集。匹配任何没有包含在方括号中的字符 [^0-9]
  • 原子组
    当我们要一次匹配多个原子的时候,需要使用原子组。原子组要通过()进行包裹。
    原子组中的内容:
    1、引用分组的时候使用到\n$n\n在匹配时引用原子组;$n指在替换时使用匹配的组数据;$&表示整个用于匹配的原字符串。
    2、原子组只是参与匹配,返回结果中进行忽略,在元子组的开头使用?:即可。
    3、为返回的原子组进行编号;结果保存在groups中。

实例一\n的作用:

let a = `
  <h1>一级标题</h1>
  <h2>二级标题</h2>
`;
let reg = /<(h[1-6])>([\s\S]*)<\/\1>/gi;
console.log(a.match(reg))

// 运行结果
["<h1>一级标题</h1>", "<h2>二级标题</h2>"]

/<(h[1-6])>([\s\S]*)<\/\1>/gi;中的\1表示前面(h[1-6])的内容

实例二$n的作用:

let a = `
  <h1>一级标题</h1>
  <h2>二级标题</h2>
`;
let reg = /<(h[1-6])>([\s\S]*)<\/\1>/gi;
console.log(a.replace(reg, "<p>$2</p>"))

// 运行结果

  <p>一级标题</p>
  <p>二级标题</p>

a.replace(reg, "<p>$2</p>")中的$2表示模式中的([\s\S]*)匹配到的内容

实例三?:的忽略作用

let hd = `
  https://www.houdunren.com
  http://houdunwang.com
  https://hdcms.com
`;

let reg = /https?:\/\/((?:\w+\.)?\w+\.(?:com|org|cn))/gi;
let reg2 = /https?:\/\/((\w+\.)?\w+\.(com|org|cn))/gi;
while ((v = reg.exec(hd))) {
  console.dir(v);
}

while ((v = reg2.exec(hd))) {
  console.dir(v);
}

// 运行结果
["https://www.houdunren.com", "www.houdunren.com", index: 3, input: "↵  https://www.houdunren.com↵  http://houdunwang.com↵  https://hdcms.com↵", groups: undefined]
["http://houdunwang.com", "houdunwang.com", index: 31, input: "↵  https://www.houdunren.com↵  http://houdunwang.com↵  https://hdcms.com↵", groups: undefined]
["https://hdcms.com", "hdcms.com", index: 55, input: "↵  https://www.houdunren.com↵  http://houdunwang.com↵  https://hdcms.com↵", groups: undefined]

["https://www.houdunren.com", "www.houdunren.com", "www.", "com", index: 3, input: "↵  https://www.houdunren.com↵  http://houdunwang.com↵  https://hdcms.com↵", groups: undefined]
["http://houdunwang.com", "houdunwang.com", undefined, "com", index: 31, input: "↵  https://www.houdunren.com↵  http://houdunwang.com↵  https://hdcms.com↵", groups: undefined]
["https://hdcms.com", "hdcms.com", undefined, "com", index: 55, input: "↵  https://www.houdunren.com↵  http://houdunwang.com↵  https://hdcms.com↵", groups: undefined]

/https?:\/\/((?:\w+\.)?\w+\.(?:com|org|cn))/gi中的?:表示忽略作用

实例四:分组别名?<groups的名称>

let hd = "<h1>houdunren.com</h1>";
console.dir(hd.match(/<(?<tag>h[1-6])[\s\S]*<\/\1>/));
// 运行结果
0: "<h1>houdunren.com</h1>"
1: "h1"
groups: {tag: "h1"}
index: 0
input: "<h1>houdunren.com</h1>"
length: 2


console.dir(hd.match(/<(h[1-6])[\s\S]*<\/\1>/));
// 运行结果
0: "<h1>houdunren.com</h1>"
1: "h1"
groups: undefined
index: 0
input: "<h1>houdunren.com</h1>"
length: 2
  • 重复次数
符号 说明
? 匹配前面一个表达式 0 次或者 1 次
{0,1} 匹配前面一个表达式 0 次或者 1 次
* 匹配前一个表达式 0 次或多次
{0,} 匹配前一个表达式 0 次或多次
+ 匹配前面一个表达式 1 次或者多次
{1,} 匹配前面一个表达式 1 次或者多次
{m,n} 匹配前面一个表达式至少 m 次 至多 n 次
  • 禁止贪婪【尽可能少的重复】
    正则表达式进行重复匹配的时候,默认是贪婪匹配,所以可以通过? 进行修饰禁止重复匹配。
使用 说明
?? 重复0或1次,但尽可能少的重复
*? 重复任意次,但尽可能少的重复
+? 重复1或多次,但尽可能少的重复
{m,n}? 重复m-n次,但尽可能少的重复
{n,}? 重复n或多次,但尽可能少的重复
  • 转义字符
    当我们搜索的字符是特殊字符的字面量,必须在它前面放一个反斜杠来转义它。
搜索字符 转义后的字符
* \*
/ \/
\ \\
  • 模式修饰 【flags】
修饰符 说明
i 不区分大小写搜索
g 全局搜索【表示有状态,即lastIndex中的内容会改变】
m 多行搜索
s 允许.匹配换行符
y 使用带有sticky标志的正则表达式,表示正则表达式将会从源字符串的lastIndex位置开始匹配【表示有状态,即lastIndex中的内容会改变】

正则的方法

test方法

执行一个检索,用来查看正则表达式与指定的字符串是否匹配。返回 truefalse
测试一:没有使用全局标记

let str = 'hello world!';
let result = /^hello/.test(str);
console.log(result);
// true

测试二:使用全局标记
使用全局标记的时候,会修改Regex对象的lastIndex的值【即上一次匹配结束的第一个字符的位置】

var regex = /foo/g;

console.log(regex.lastIndex); // 0
regex.test('foo'); // true

console.log(regex.lastIndex); // 3
regex.test('foo'); // false

exec方法

在一个指定字符串中执行一个搜索匹配。返回一个结果数组或null。如果正则表达式中使用的标记g,那么RegExp对象中的lastIndex的值就会动态变化。

测试:使用带有g的正则表达式

var myRe = /ab*/g;
var str = 'abbcdefabh';
var myArray;
while ((myArray = myRe.exec(str)) !== null) {
  var msg = 'Found ' + myArray[0] + '. ';
  msg += 'Next match starts at ' + myRe.lastIndex;
  console.log(msg);
}

// 测试结果
Found abb. Next match starts at 3
Found ab. Next match starts at 9
注意事项

如果正则表达式的模式修饰没有使用全局匹配的时候(g)的时候,使用while就是陷入死循环。

字符串中使用正则表达是的函数

String.match()

一个在字符串中执行查找匹配的String方法,它返回一个数组,在未匹配到时会返回 null。

var str = 'For more information, see Chapter 3.4.5.1';
var re = /see (chapter \d+(\.\d)*)/i;
var re2 = /see (chapter \d+(\.\d)*)/ig;
var found = str.match(re);
var found2 = str.match(re2);

console.log(found);
// logs [ 'see Chapter 3.4.5.1',
//        'Chapter 3.4.5.1',
//        '.1',
//        index: 22,
//        input: 'For more information, see Chapter 3.4.5.1' ]

console.log(found2)
// [ "see Chapter 3.4.5.1" ]

注意事项
  • 如果传递的函数不是一个正则表达式,则会默认使用new RegExp()构造函数进行转变成正则表达式。

String.matchAll()

参数:正则表达式。
一个在字符串中执行查找所有匹配的String方法,它返回一个迭代器(iterator)。

注意事项
  • 正则表达式的模式必须是全局的,否则会报出异常。

String.replace()

参数:正则表达式|字符串、替换的内容|函数
一个在字符串中执行查找匹配的String方法,并且使用替换字符串替换掉匹配到的子字符串。

注意事项
  • 该方法并不改变调用它的字符串本身,而只是返回一个新的替换后的字符串。
  • 使用此方法,替换的内容可以使用特殊变量:$n获取匹配到的内容,增加替换的灵活性。

String.search()

参数:正则表达式。
一个在字符串中测试匹配的String方法,它返回匹配到的位置索引,或者在失败时返回-1。

注意事项
  • 正则表达式的模式必须是全局的,否则会报出异常。

String.split()

参数:划分的标准【可选】、划分的个数限制【可选】

一个使用正则表达式或者一个固定字符串分隔一个字符串,并将分隔后的子字符串存储到数组中的 String 方法。

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

推荐阅读更多精彩内容