正则表达式好难学!9个易懂的例子,轻松入门JavaScript正则

正则表达式是用来描述字符模式的对象。它被用来在文本中执行模式匹配(pattern-matching)以及”查找-替换”(search-and-replace)的任务。

前端开发中,我们常常会在这些地方看到正则:

  • 验证手机号,邮件,身份证号等是否合法。
  • 删除字符串前后多余的空格。
  • 从浏览器的UserAgent信息中提取出当前是什么浏览器,以及浏览器的版本。来做一些兼容性处理。

正则表达式给人的感觉:很难读懂,也难写。谁知道下面2个正则是干嘛的吗😂

  • /<\/?[a-zA-Z]+(\s+[a-zA-Z]+=".*")*>/g
  • /^w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*$/ /^[a-zA-Z][a-zA-Z0-9_]{2,6}$/

为什么要学习正则?

正则表达式用简短的代码,能实现非常复杂的文本查找替换操作。用字符串的api来实现同样的功能,代码会复杂的多,代码量也会多的多。比如,验证手机号是否合法。我们假定,合法的手机号指:以1开头的11位数字。

用字符串的api,这么写:

function validPhone(phone) {
  let isValid = false
  phone += ''
  if (phone.length === 11 && phone[0] === '1' && !isNaN(phone)) {
    isValid = true
  }
  return isValid
}

用正则,一行代码搞定:

/^1\d{10}$/.test(phone)

可见,熟练掌握正则表达式,能极大的提升开发文本的查找替换功能的开发效率。

例子

学习正则表达式的最好方法是从例子开始,理解例子之后再自己对例子进行修改。下面,我们就开始吧~

例子1: 精确匹配

查找文本中是否包含cat。代码实现如下:

/cat/.test('I have a cat.') // 返回true
/cat/.test('I have a dog.') // 返回 false

上面的代码中,/cat/ 创建了一个匹配 cat 的正则。有两种方式创建正则对象:

  1. /匹配模式/。 如 /cat/
  2. new RegExp(匹配模式字符串)。 如 new RegExp('cat')

这两种方式的不同点在于,方式2支持传入变量。

test 是正则对象上的方法,用来检索字符串中是否包含指定的值。返回 true 或 false。还有一个常见的正则方法 exec,用来检索字符串中指定的值。

字符串的splitsearchreplacematch方法支持传入正则。

例子2: 匹配一类字符:数字,字母,空格等

查找文本是否有数字。代码实现如下

/\d/.test('3C') // true

常见字符类型的匹配方式如下:

  • .: 匹配一个任意字符。
  • \d: 匹配一个数字。
  • \D: 匹配一个非数字字符。
  • [a-z]: 匹配一个小写字母。
  • [A-Z]: 匹配一个大写字母。
  • [\u4e00-\u9fa5]: 匹配一个中文字。
  • \w: 匹配字母、数字、下划线。等价于[A-Za-z0-9_]。
  • \s: 匹配任何空白字符,包括空格、制表符、换页符等等。
  • \S: 匹配任何非空白字符。
  • \\: 匹配\。

例子3: 匹配指定范围内字符

查找文本中是否包含 ab12 中任意一个字符。代码实现如下:

/[ab12]/.test('a') // true
/[ab12]/.test('b') // true
/[ab12]/.test('1') // true
/[ab12]/.test('2') // true

[指定范围] 来匹配指定范围内字符。 用 [^指定范围] 来匹配不在指定范围内的字符。如:/[^a-z]/ 匹配非小写字母。

例子4: 匹配重复

查找文本中是否包含5个a。蛮干版,代码实现如下:

/aaaaa/.test('aaaaa') // true

优雅版:

/a{5}/.test('aaaaa') // true

查找文本中是否包含3个ab。代码实现如下:

/(ab){3}/.test('ababab') // true

注意,上面的代码中,用括号包起来ab,把ab变成一个整体。不加括号,匹配的是abbb。

重复字符的匹配方式如下:

  • *: 匹配前面的子表达式零次或多次。
  • +: 匹配前面的子表达式一次或多次。
  • ?: 匹配前面的子表达式零次或一次。
  • {n}: 匹配前面的子表达式确定的 n 次。
  • {n,}: 匹配前面的子表达式至少 n 次。
  • {n,m}: 匹配前面的子表达式 n 到 m之间。

更多例子:

/a\*/ // 匹配任意个a
/https?/ // 匹配 http 和 https
/1\d{10}/ // 11位手机号

例子5: 匹配文本以...开始和以...结尾

查找文本是否以字母开头,以数字结尾。代码实现如下:

/^[a-zA-Z].*\d$/.test('ab1') // true

^用来匹配输入字符串的开始位置。$用来匹配输入字符串的结束位置。

例子6: 匹配多种情况

查找文本是包含138或包含159。代码实现如下:

/(138|159)/.test('138') // true
/(138|159)/.test('159') // true

|用来匹配多种情况。注意,情况包含的字符数量超过一个,要用括号包起来。反例:

/138|159/.test('138') // false
/138|159/.test('13859') // true
/138|159/.test('13159') // true

例子7: 匹配模式

查找文本中是否全部是字母。实现方法1:

/^[a-zA-Z]*$/.test('abcABC') // true

方法2:

/^[a-z]*$/i.test('abcABC') // true

方法2中的i是匹配模式。常见的匹配模式如下:

  • g : 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)
  • i : 执行对大小写不敏感的匹配。
  • m : 执行多行匹配。

一个正则可以有多个模式,表示对多个模式的叠加。如 /a/ig

例子8: 匹配的争夺:贪婪模式和非贪婪模式

匹配文本中的非空白字符和数字,要尽量多匹配数字。代码实现如下:

/(\S+?)(\d*)/.exec('a123') // ["a123", "a", "123"]
// 这种写法,会尽可能多的匹配非空白字符:/(\S+)(\d*)/.exec('a123') // ["a123", "a123", ""]

当正则表达式中包重复的限定符(*+,?, {n}, {n,}, {n,m})时,匹配模式是贪婪的:匹配尽可能多的字符。在重复的限定符后加?,会将匹配模式改成非贪婪的:匹配尽可能少的字符。

例子9: 文本替换

将文本中单词"cat"替换成"dog"。代码实现如下:

'I have a cat.'.replace(/cat/, 'dog') // 运行结果 I have a dog.

将文本中所有的单词"cat"替换成"dog"。代码实现如下:

'cat,cat,cat'.replace(/cat/g, 'dog') // 运行结果 dog,dog,dog

将第2个出现的"cat"替换成"dog"。代码实现如下:

let appearNum = 0
let res = 'cat,cat,cat'.replace(/cat/g, (matched) => {
  appearNum++
  if(appearNum === 2) {
    return 'dog'
  } else {
    return matched
  }
})
console.log(res) // 运行结果 cat,dog,cat

推荐工具

RegExr

正则测试工具。

Regulex

JavaScript 正则可视化工具。展示效果:


Regulex运行结果

总结

熟练掌握正则表达式,能极大的提升开发文本的查找替换功能的开发效率。大家有必要去认真学一下。

本文介绍了正则的基础。正则博大精深,还有很多值得研究。

参考&推荐阅读

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

推荐阅读更多精彩内容

  • `>本文是 Jan Goyvaerts 为 RegexBuddy 写的教程的译文,版权归原作者所有 在本文中讲述了...
    极客圈阅读 2,055评论 0 5
  • 本文译自 制作正则引擎的作者 Jan Goyvaerts 为工具 RegexBuddy 写的教程版权归原作者所有注...
    极客圈阅读 3,247评论 0 25
  • 正则表达式到底是什么东西?字符是计算机软件处理文字时最基本的单位,可能是字母,数字,标点符号,空格,换行符,汉字等...
    狮子挽歌阅读 2,129评论 0 9
  • 注:本篇文章只为方便查看,特此保留,如有冒犯,敬请谅解!!! 本文目标 30分钟内让你明白正则表达式是什么,并对它...
    阿杰Alex阅读 1,472评论 0 10
  • 学了NLP之后的我,最大的变化是:遇到很多事情挤在一起到来的时候,我发现自己特别有天赋,很强的规划能力和分配能力!...
    A忆思特教育赵敏阅读 114评论 0 2