壹 ❀ 引

对于初学正则的同学来说,^$这两个看似简单的字符却在使用中总让匹配结果超出我们的预期,^什么时候表示行首什么时候表示反义?^ $两个一起写表示什么含义?今天我们就来详细聊聊这两个字符。

 贰 ❀ 关于^与$

先解释^与$概念,很简单的两句话,先留个印象。

^ 脱字符:匹配开头,若存在多行匹配多行的行头。

$ 美元符:匹配尾部,若存在多行匹配多行的尾部。

我们知道正则是一种匹配模式,要么匹配字符,要么匹配位置。这里我们得从这两种匹配情况分别解释这两个字符。

1.从匹配字符角度

当用于匹配字符时,^与$更多是作为匹配出精准结果的辅助条件,我们先看个简单的例子:

'123'.match(/\d/g);//[1,2,3]

很好理解,全局(注意结尾有个g)匹配单个任意数字,很明显1,2,3都符合条件,所以这里找到了三个匹配结果;我们分别添加 ^ 与 $ 再看:

'123'.match(/^\d/g);//[1]
'123'.match(/\d$/g);//[3]

此时 ^\d 只能匹配到1,而 \d$ 只能匹配到3,你肯定就纳闷了,不对啊,我正则后面不是有个g表示全局匹配吗,怎么只匹配一个了呢?以 ^\d为例,此时的匹配条件其实是找开头位置后的一个任意数字,\d$ 表示匹配结尾前的一个任意数字。开头和结果对于一个不换行的字符串都只有一个,所以自然只能找到一个数字了,现在能理解前面所说的^$作为辅助条件的意思了吗。

那么我们现在将数字换行,再看:

'12\n34'.match(/^\d/mg);//[1,3]
'12\n34'.match(/\d$/mg);//[2,4]

由于存在换行,导致现在有两个开头位置和两个结尾位置(注意匹配中使用了m,表示换行匹配),所以匹配结果也变成了两个,不难理解吧。

2.从匹配位置角度

正则除了根据规则匹配对应的字符,还有一个强大的功能就是匹配位置。什么是位置呢?以字符 1234 为例,每个箭头都代表一个位置,其中第一个箭头的位置就是 脱字符 ^,结果位置就是美元符$, 如下图:

所以当我们在匹配位置时,^$也成为了我们需要匹配的结果,例如,我需要将 1234 首尾位置加上花朵:

'1234'.replace(/^|$/g, '❀');// "❀1234❀"

当然,在匹配位置时^与$也是帮助我们精确位置的辅助条件,比如常用的千位分隔符正则:

'12345678'.replace(/(?!^)(?=(\d{3})+$)/g, ',');// "12,345,678"

这段正则的意思,就是从右往左找,每隔三位数字前面的位置替换成逗号,同时排除字段头部位置,因为当不排位开头位置,只要字符长度是三的倍数,就会导致头部也会出现逗号的尴尬局面,例如:

'123456789'.replace(/(?=(\d{3})+$)/g, ',');// ",123,456,789"

所以针对千位分隔符正则中的 ^ 与 $ 而言,^起到了排除开头位置的作用,而$起到了改变正则匹配的方向,由默认的从左到右变成了从右到左每隔三位的查找。

3.反义字符组

^除了作为脱字符表示从头匹配,开头位置两个含义外,还能作为反义字符使用,例如,我想匹配除了123之外的任意字符:

/[^123]/.test(1); //false
/[^123]/.test(2); //false
/[^123]/.test(3); //false
/[^123]/.test(4); //true

这里[^123]就表示除了123之外的意思,那么我们怎么知道^什么时候表示反义,什么时候表示开头位置呢?很简单,因为当它只有放在字符组中时才叫反义字符组,所以当然是只有出现在[]中时才是反义的意思。

4.^与$同时出现在正则前后表示什么?

对于新手而言,^$同时出现确实有点误解人,毕竟我们前面说^表示从左到右,$能起到从右到左的作用,同时出现难道匹配左右夹击?其实同时写时只是限制字符的起点与终点,我们来看个例子:

/123/.test('   123   '); //true
/^123$/.test(' 123 '); //false

第一个输出true,这是因为被检测的字段只要有123这三个字段就行了,不关心你123前后还有什么。而第二个我们利用^$限时了字符的两端,也就是说如果你test想为真,那么你的字符开头后面必须是1,结尾前面必须是3,字符的开头结尾被固定死了。一般在验证表单输入是否正则,我们都会加上^$。

那么关于^与$的解析就说到这了,太晚了,本文结束。

随机推荐

  1. Anaconda中启动Python时的错误:UnicodeDecodeError: 'gbk' codec can't decode byte 0xaf in position 553

    今天,在Anaconda prompt启动python遇到了如下错误: UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0xaf in positi ...

  2. css三大特效之继承性

    css三大特效之继承性

  3. JDK API1.6常用方法

    一.String类 常见用法 : (String类代表字符串,JAVA程序中的所有字符串字面值(如“abc”)都作为此类的实例实现,字符串是常量,他们的值在创建之后不能更改,字符串缓冲区支持可变的字符 ...

  4. vim介绍、颜色显示和移动光标、一般模式下移动光标及复制、剪切和粘贴

    第4周第4次课(4月12日) 课程内容: 5.1 vim介绍5.2 vim颜色显示和移动光标5.3 vim一般模式下移动光标5.4 vim一般模式下复制.剪切和粘贴 5.1 vim介绍 centos7 ...

  5. yarn和npm的对比以及yarn的使用

    0--前言 为什么要使用yarn,如果你从事前端开发有些年头了,那你肯定对npm又爱又恨,爱就不说了,恨嘛,就是NPM经常奇慢和卡顿,这还能忍,经常各种错误就没法忍了,尤其是他人创建的项目,自己在安装 ...

  6. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(8)- 从Serial(1-bit SPI) NOR恢复启动

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的1-bit SPI NOR恢复启动. 在前几篇里痞子衡介绍的Boot Device都属于主动启动的 ...

  7. 从UI设计转向前端的艰辛过程,从背单词开始。。。

    很纠结到底是继续做UI设计还是转行前端呢?从刚开始的害怕代码到接触代码又喜欢代码的过程,我在想我是不是太飘了,我感觉我做事就是三分钟热度.我感觉学前端对我最大的阻碍就是英语单词了,10个单词里面最起码 ...

  8. 理解Redis的单线程模式

    0.概述 本文基于的Redis版本为4.0以下,在Redis更高版本中并不是完全的单线程了,增加了BIO线程,本文主要讲述主工作线程的单线程模式. 通过本文将了解到以下内容: Redis服务器采用单线 ...

  9. 带着canvas去流浪系列之二 绘制折线图

    [摘要] 用canvasAPI实现echarts简易图表 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvasAPI绘制 ...

  10. Reactive(3)5分钟理解 SpringBoot 响应式的核心-Reactor

    目录 一.前言 二. Mono 与 Flux 构造器 三. 流计算 1. 缓冲 2. 过滤/提取 3. 转换 4. 合并 5. 合流 6. 累积 四.异常处理 五.线程调度 小结 参考阅读 一.前言 ...