Javascript基础——Javascript语言核心(7):正则表达式的模式匹配

正则表达式的模式匹配

正则表达式(regular expression)是一个描述字符模式的对象。

推荐一个正则表达式的网站:https://regex101.com/

10.1 正则表达式的定义

Javascript中的正则表达式用RegExp对象表示。有如下方式进行创建:

  • RegExp()构造函数
  • 特殊的直接量语法,定义为包含在一对斜杠(/)之间的字符
//用来匹配以s结尾的字符串
var pattern = /s$/;
10.1.1 直接量字符

在正则表达式中,具有特殊含义的标点符号:
^ $ . * + ? = ! : | \ / ( ) [ ] { }

10.1.2 字符类

将直接量字符单独放进方括号内就组成了字符类(character class)。可以匹配它所包含的任意字符。

^定义否定字符类,匹配所有不包含在方括号内的字符。

举例:

  • /[abc]/ Matches either an a, b or c character
  • /[^abc]/Matches any character except for an a, b or c
  • /[a-zA-Z0-9]/匹配拉丁字母(含所有大小写)和数字

由于某些字符类非常常用,所以使用了特殊字符的转义字符来表示他们:

字符等价匹配
.除换行符和其他Unicode行终止符之外的任意字符
\w[a-zA-Z0-9]大小写拉丁字母及数字
\W[^a-zA-Z0-9]任何不适ASCII字符组成的单词
\s任何Unicode空白符
\S任何**非**Unicode空白符的字符
\d[0-9]任何ASCII数字
\D[^0-9]除了ASCII数字之外的任何字符
\b退格直接量(特例)
10.1.3 重复

在正则模式之后跟随用以指定字符重复的标记,如下:

字符等价含义
{n,m}匹配前一项至少n次,但不能超过m次
{n,}匹配前一项n次或更多次
{n}匹配前一项n次
?{0,1}匹配前一项0次或1次
+{1,}匹配前一项1次或多次
*{0,}匹配前一项0次或多次

示例:

  • /\d{2,4}/匹配2-4个数字
  • /\w{3}\d?/匹配三个字母和可选的一个数字
  • /\s+java\s+/匹配前后带有一个或者多个空格的字符串“java”

注意:在使用*?时要注意,由于这些字符可能匹配0个字符,因此他们允许什么都不匹配。例如,正则表达式/a*/匹配字符串“bbbb”,因为这个字符串含有0个a。

10.1.4 选择、分组和引用
(1) 字符|

字符|用于分隔供选择的字符。

例如:

  • /ab|cd|ef/匹配“ab”或“cd”或“ef”
  • /\d{3}|[a-z]{4}/匹配3位数字或4个小写字母

注意,选择项的尝试匹配次序从左到右,直到发现匹配项。一旦匹配上,就忽略之后的匹配项。例如,/a|ab/匹配字符串“ab”时,只能匹配第一个字符。

(2) 圆括号

作用1:

把单独的项组合成子表达式,以便可以像处理一个独立的单元那样对单元内的项进行处理。

示例:

  • /java(script)?/匹配字符串“java”,其后可以有“script”,也可以没有
  • /(ab|cd)+|ef/匹配字符串“ab”或者“cd”的一次或多次重复,也可匹配“ef”

作用2:

在完整的模式中定义子模式。当一个正则表达式成功地和目标字符串相匹配时,可以从目标串中抽出和圆括号中的子模式相匹配的部分。通过在字符\后加一位或多位数字来实现。\3引用第3个带圆括号的子表达式。

注意,嵌套表达式以左括号的位置来计算。例如:

/(java(script)?)\w*/中嵌套的子表达式(script)可以用\2指代。

对正则表达式中前一个子表达式的引用,并不是对字表达式的模式引用,而是与那个模式相匹配的文本引用

例如,匹配位于单引号或者双引号内的0个或多个字符:

/(['"])[^'"]*\1/

10.1.5 指定匹配位置

指定匹配发生的合法位置的元素称为正则表达式的

最常用的锚元素:^匹配字符串的开始$匹配字符串的结束

例子:
(1) /^java$/:匹配前后都没有其他内容的java。
hello java, javasript world
java

(2) /\bjava\b/:匹配java单词
hello java
javasript world
java

(3) /java(?=:)/:匹配其后有冒号的java字符
hello java, javasript world
java
java: hello

(4) /java(?!:)/:匹配其后没有冒号的java字符
hello java, **java**sript world
java
java: hello

锚字符汇总:

字符含义
^匹配字符串的开头,在多行检索中,匹配一行的开头
$匹配字符串的结尾,在多行检索中,匹配一行的结尾
\b匹配一个单词的边界,就是位于字符\w和\W之间的位置,或位于字符\w和字符串的开头或者结尾之间的位置(注意,10.1.2中介绍的[\b]匹配的是退格符)
\B匹配单词边界的位置
(?=p)零宽正向先行断言,要求接下来的字符都与p匹配,但不能包括匹配p的那些字符
(?!p)零宽负向先行断言,要求接下来的字符都与p匹配
10.1.6 修饰符

修饰符是放在第二条斜线之后的,用以说明高级匹配模式的规则。

字符含义
i执行不区分大小写的匹配
g执行一个全局匹配,即找到所有的匹配,而不是在找到第一个之后就停止
m多行匹配模式,^匹配一行的开头和字符串的开头,$匹配行的结束和字符串的结束

10.2 用于模式匹配的String方法

String支持如下4中正则表达式的方法:

参数:正则表达式

返回:第一个与之匹配的字符串的其实位置,如果找不到匹配项,返回-1

注意:该方法不支持全局检索,自动忽略修饰符g。

"JavaScript".search(/script/i); //=> 4
(2) replace()

参数1:正则表达式

参数2:用来替换的字符串

返回:替换后的字符串

//----例1----
//将不区分大小写的javascript替换成正确大小写的JavaScript
"javascript is JAVAscript".replace(/javascript/gi,"JavaScript"); //=> "JavaScript is JavaScript"

//----例2----
//将文本中的双引号改为中文的双引号
var text = 'java,"你好"';
var quote=/"([^"]*)"/g;      //中间的内容区域不能包含引号
text.replace(quote, '“$1”'); //=> "java,“你好”"

如果在替换字符串中出现了$加数字,那么replace()将用与指定的子表达式相匹配的文本来替换这两个字符。

(3) match()

参数:正则表达式

返回:一个由匹配结果组成的数组

"1 plus 2 equals 3".match(/\d+/g) //=> ["1", "2", "3"]
"1 plus 2 equals 3".match(/\d+/) //=> ["1", index: 0, input: "1 plus 2 equals 3", groups: undefined]
(4) split()

参数:分隔符的正则表达式

返回:字符串数组

//指定分隔符可允许两边有任意多的空白符
"1  , 2,3,4".split(/\s*,\s*/); //=> ["1", "2", "3", "4"]

10.3 RegExp对象

正则表达式是通过RegExp对象来表示的。

(1) RegExp()构造函数

参数1:正则表达式主体部分,两条斜线之间的文本。(转义字符需要将\替换为\\

参数2(可选):正则表达式修饰符

var zipcode = new RegExp("\\d{3}","g"); //=> /\d{3}/g

RegExp()构造函数非常有用,特别在需要动态创建正则表达式的时候。

10.3.1 RegExp的属性

示例都是以上文中定义的zipcode为例。

属性名只读含义示例
source包含正则表达式的文本zipcode.source; //=> "\d{3}"
global正则表达式是否带有修饰符gzipcode.global; //=> true
ignoreCase正则表达式是否带有修饰符izipcode.global; //=> false
multiline正则表达式是否带有修饰符mzipcode.global; //=> false
lastIndex如果匹配模式带有g修饰符,这个属性存储在整个字符串中下一次检索的开始位置zipcode.lastIndex; //=> 0
10.3.2 RegExp的方法
(1) exec()

对一个指定的字符串执行一个正则表达式。没有匹配返回null,找到一个匹配返回一个数组。

zipcode.exec("123,a,456,d"); //=> ["123", index: 0, input: "123,a,456,d", groups: undefined]
zipcode.lastIndex; //=> 3

zipcode.exec("123,a,456,d"); //=> ["456", index: 6, input: "123,a,456,d", groups: undefined]
zipcode.lastIndex; //=> 9

zipcode.exec("123,a,456,d"); //=> null
zipcode.lastIndex; //=> 0

第一次调用exec()时,匹配到了123,lastIndex为下一次检索开始的位置,则是3。第二次匹配后,需开始下次检索的位置变为9。当没有发现匹配结果后,lastIndex会重置为0。

(2) test()

参数为一个字符串,用test()对某个字符串进行检测,如果包含匹配的结果,则返回true。

zipcode.test("123,a,456,d"); //=>true

var pattern= /java/i;
pattern.test("Javascript"); //=> true
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值