js中的正则表达式

正则表达式等名称并不能让人一下就能明白是什么意思,我认为称之为 规则表达式 更为合理,就是描述一个字符串规则的表达式。

语法

正则表达式的语法有两种,下面第一种语法稍显 怪异,但确实是合法的并且相对方便,推荐。

var reg = /pattern/modifiers;
//或者
var reg = new RegExp(pattern,modifiers);

↓使用

var a = /Hello/;
//或者
var a = new RegExp('Hello World');var str = 'Hello World';
str.search(a); //返回0,这是 a 在 str 中匹配到的字符的位置

上面就是一个匹配字符”Hello”的一个正则表达式。

修饰符

字符含义
g全局匹配
i忽略大小写
m匹配多行
var a = /a/;
var str = 'abcabc';
str.match(a); //['a'] str里面有两个a但是只匹配了一个,想要匹配字符串中全部符合表达式的字符串怎么办?//g
var aGlobal = /a/g;
str.match(aGlobal); //['a', 'a'] 这样就匹配了str中所有符合的字符//i
var strI = 'abcAbc';
strI.match(aGlobal); //['a'] 返回一个元素 'A' 没有被匹配到,因为字符的大小写不同,想要忽略大小写怎么办?var aGlobalIgnore = /a/gi;
strI.match(aGlobalIgnore); //['a', 'A'] 这样大写的'A'也匹配到了//m
var str2 = 'abc\nabc';
str2.match(aGlobal);  //['a', 'a']var aNM = /^a/g;  // ^是匹配位置的元字符表示一行开始位置,也就是说"bacd"中的"a"是不会被匹配的,只会匹配出现在行首位置的"a"
str2.match(aNM); //['a'] 默认情况下一个字符串无论字符串内有没有"\n"换行符都只有一个字符串开始位置^和一个字符串结束位置$,但是如果使用了"m"修饰符那么"\n"就会使每一行都有一个"^"开始位置和一个"$"结束位置var aMultiline = /^a/gm;
str2.match(aMultiline); //['a', 'a'] 这样两行的开头的a都被匹配到了

补充:m必须作用于 \n 的字符串并且正则表达式中要有 \^ 或者 $ 的位置匹配规则才会有意义。

量词/重复

在正则表达式中可以很轻松的表示重复

var a = /a/;
var str = 'aaaba';
str.match(a); // ['a'] 字符串中有3个连续的a,怎么匹配这3个连续的a呢?
var a1 = /a{3}/; // ['aaa'],{3} 表示前面的模式重复3次,也可以写成 --> /aaa/ 但是要是100个怎么办???
符号含义
+匹配1次或者无数次
*匹配0次或者无数次
?匹配1次或者0
{n}匹配重复n次
{n,}匹配至少重复n次
{m, n}匹配>=m次,<=n次

贪婪与懒惰

当正则表达式进行匹配的时候一次会尽量匹配最多符合的字符,这就是所谓的贪婪。

var a = /a+/;
var str = "aaa";
str.match(a); // ["aaa"] 这里返回了正则能匹配的所有的字符,并不是在遇到第一个合适的就结束匹配, * 元字符会尽可能多的匹配,体现了正则的贪婪模式。var a1 = /a+?/; // 这个新增的?就告诉正则要尽可能少的匹配字符,开启了懒惰模式
str.match(a1);  // ["a"] 这就只返回一个符合条件的结果,即使后面还有符合条件的也不会继续匹配
字符含义
*贪婪
+贪婪
{n, }贪婪
*?懒惰
+?懒惰
{n,}?懒惰

元字符

元字符是在正则表达式中有特殊意义的字符,所以他们不能表示自身,在正则表达式中如果要匹配他们则需要转义(见下文)。

现在要匹配一个字符串(adef2ew)中出现的一个数字,但是却并不知道 具体 是哪个数字,这时候我们就可以使用元字符(\d)来表示我们需要寻找的这一类字符(数字)。

var a = /\d/;
var str = 'adef2ew';
str.match(a); // ['2']

元字符就是在正则表达式中有着特殊含义的一些字符,以下是一些元字符(不是全部,本文中所有表格中的字符都是元字符),可以在正则表达式中发挥难以想象的威力。

符号含义
.(点)除了换行符的所有字符
\wa-z、A-Z、0-9,以及下划线, 包含 _ (下划线) 字符
\s制表符,回车等空白符
\d数字

位置匹配

还有可能我们要匹配一个单词(hello),但是我们并不想匹配(helloword)中的(hello),我们要这样的(hello word),它是一个单词,并不是一个单词的组成部分。我们可以这样:

var a = /\bhello\b/;
var str = 'helloworld';
str.match(a); // nullvar str1 = 'hello world';
str1.match(a); // ['hello']//上面用到了\b表示是单词的边界(开头或者结尾),也就是该元字符匹配了一个位置。

现在想要匹配一个字符串(.jpg),但是要求是这个字符串必须要在一个字符串的结尾,不能在字符串的中间。

var a = /\.jpg/; // . 需要用 \ 转义否则表示的不是 . 字符本身。
var str= 'hehe.jpghaha';
str.match(a); // ['.jpg'] 这里匹配到了,但是我们要的不是这样的,这个字符串并没有出现在所在字符串的结尾var str1 = 'hehehaha.jpg';
var a1 = /\.jpg$/; // $ 表示的是匹配字符串结尾位置
str.match(a1); // null 并没有获取到匹配的内容
str1.match(a1); // ['.jpg'] 获取到了
符号含义
\b单词边界(什么是边界?)
$结束
^开始

转义

如果我要匹配的字符串中有上面的元字符表示的字符串怎么办?这时就需要用到转义。

符号含义
\转义特殊字符
var a = /./; //这个表示的是匹配任意除了换行的字符
var b = /\./; //这个才是表示匹配**.**字符
var c = /\\/; // 匹配 \ 字符串

在[](下文的集合)中的元字符可转义也可不转义,主要取决于该字符有没有歧义。

集合

有时我们只想匹配a-z的小写字母并不想匹配大写的或者其他字符怎么办?

var a = /[a-z]/; //这就表示匹配一个字母必须是小写字母
var b = /[1-9]/; //简写如1,2,3,4,5,6,7,8,9可以写成如下形式
var d = /[1-9a-zA-Z]/; //表示数字和字母的集合

还有可能我们可以匹配所有字符但是除了所有小写字母

var a = /[^a-z]/;
var str = 'a';
str.match(a); //nullvar str1 = '1a';
str1.match(a); //['1']

以下是一些集合的含义。

字符含义
[123]匹配1,2,3中任意一个
[1-9a-zA-Z]匹配数字小写字母和大写字母
[^a-z]匹配除了小写字母的所有字符

分支

分支可以理解为正则表达式的集合,回想一下分组 [abc] 表示的是 abc ,但是如果我想表示 a11a11 (1是数字不是字母l) 这个怎么办?

[a11a11]这样吗? 这样好像 不正确。。。

使用集合并不能做到,因为集合只是表示的单个字符的集合,而上面的问题涉及的并不只有一个字符,而是一个表达式才能完整表示的,所以这时就需要用到分支(|),* 表示或的意思 *

var a = /a1|1a|11/;
var str = 'a1';
str.match(a); // ['a1']var str1 = '1a';
str1.match(a); // ['1a']var str2 = '11';
str2.match(a); // ['11']

所以分支可以表示表达式的集合。

分组 / 子表达式

str.replace( search, ‘$1’, );
在前面提到的重复可以轻松实现 a,aa,aaa,的匹配(/a+/),但是如果要是匹配的超过了一个字符的重复如he,hehe,hehehe,hehehehe这样的怎么办呢?

提醒:通过这个问题也能知道 * 重复只能重复之前的一个字符 *

var a = /he+/; //这样吗?但是这个匹配的是 he,hee,heee...这种字符,所以不行。
var a1 = /he|hehe|hehehe/ //这样吗? 这也太麻烦了,并且还不是一个完整的集合
var str = 'zhouheheabcdefg';
str.match(a1); //['he'] 这样确实可以实现一部分var a2 = /(he)+/;
var str1 = 'zhouheheheheabcdefg';
var str2 = 'zhouheheheheheheabcdefg';
str1.match(a2); // ['hehehehe', 'he']
str2.match(a2); // ['hehehehehehe', 'he']
//这里正确的匹配了字符串中所有的 he 的重复,无论重复几次

分组的捕获

\1 来引用表达式中第一个分组(子表达式)
但是这个有一个弊端就是\1是相对位置,如果前面插入了一个分组(子表达式)那就完蛋了。

匹配 重复的单词,比如 ha ha

var a = /\b(\w+)\b\s+\1\b/; // 这里的 \1 就是对分组 (\w+) 的引用
var str  = 'ha ha abcd';    // 这里的 ha ha符合条件所以被捕获
var str2 = 'ha he abcd';    // 这里 ha 后面的单词是 he 不一样所以没有被捕获
str.match(a);  // ["ha ha", 'ha']
str2.match(a); // null

非捕获组

正则表达式匹配成功的不一定会捕获,比如位置元字符 ^,$,\b 等和零宽断言都是匹配了但是并不捕获。

var a = /(?:a)/;
var str = 'abcdefg';
str.match(a);  // ['a'] 按照下面第一个注解说的 () 分组的内容会被捕获到结果的对应的组号处 (?:a) 是一个分组。但是结果却是没有捕获,因为(?:) 的意思就是不捕获到分组,并且不会分配组号。var b = /(a)/;
str.match(b);  // ['a', 'a']

分组就是把一个规则看成一个整体,整个正则表达式就是一个大的分组,在这个大的分组中可以有很多子分组。

注:上面用match方法捕获有分组的正则表达是的时候返回值([‘hehehehe’, ‘he’])中不止一个元素,第二个元素就是正则表达式中分组所匹配捕获的内容。(上面一段话整个表达式就是一个分组,所以整个表达式匹配捕获的内容在最前面,后面是子分组所捕获的内容,子分组的顺序就是在数组中捕获内容的顺序)

常用分组语法

符号含义
(exp)匹配 exp ,并捕获文本到自动命名的组里
(?:exp)不捕获文本并且不给该分组分配组号[1]
(?=exp)匹配 exp 后面的位置
(?<=exp)匹配 exp 前面的位置
(?!exp)匹配后面不是 exp 的位置
(?<!exp)匹配前面没有exp 的位置

正则中的前和后怎么理解?

在匹配一个字符串的时候是从左往右匹配的,所以:

var a = /g/;
//         ---匹配方向--->
//         后---------->前
var str = 'abcdefghijklmn';
// 和正常认为的前和后不一样

断言

零宽度正预测先行断言

需要匹配一个 y,并且这个 y 的前面要有 ing,这样的要求上面的知识就不能做到。

var a = /y(?=ing)/; // 匹配 y 前面有 ing 的 y
var str = 'ying';   // y 的前面有 ing,所以 y 被匹配
var str2 = 'yang';  // y 的前面是 ang,不是 ing, 所以 y 没有被匹配
str.match(a);  // ['y'] 这里匹配到了结果
str2.match(a); // null  这里的字符串不满足条件所以没有匹配到结果

零宽度正回顾后发断言

需要匹配一个 ing,并且这个 ing 的后面要有 y

var a = /(?<=y)ing/; // 匹配 ing 后面有 y 的 ing
var str = 'ying';    // ing 后面有 y,所以 ing 被匹配
var str2 = 'aing';   // ing 后面是 a,不是 y,所以 ing 没有被匹配
str.match(a);  // ["ing"]
str2.match(a); // null

零宽度负预测先行断言

需要匹配一个 y,并且这个 y 的前面不能有 ing。

var a = /y(?!ing)/; // 匹配 y 前面没有 ing 的 y
var str = 'yang';   // y 前面是 ang,不是 ang,所以 y 被匹配
var str2 = 'ying';  // y 前面是 ing,所以 y 没有被匹配
str.match(a);  // ['y']
str2.match(a); // null

零宽度负回顾后发断言

需要匹配一个 ing,并且这个 ing 的后面不能有 y。

var a = /(?<!y)ing/; // 匹配 ing 后面没有 y 的 ing
var str = 'aing';   // ing 后面是 a,不是 y,所以 ing 被匹配
var str2 = 'ying';  // ing 后面是 y,所以 ing 没有被匹配
str.match(a);  // ['ing']
str2.match(a); // null

对断言名称的理解:

零宽度:只匹配不捕获

正:有

负:没有

预测,先行:向前

回顾,后发:向后

案例

验证邮箱是否合法

// 邮箱格式: 用户名 @ 域名
var a = /^[1-9a-zA-z_\-]+@[a-zA-Z0-9_\-]+(\.[a-zA-Z0-9_\-]+)+$/;
var str = 'haha@qq.com';
str.match(a); // ["haha@qq.com", ".com"]

格式化千分位

将123456789格式化成123,456,789

var a = /(\d)(?=(?:\d{3})+$)/g;
var str = '123456789';
str.replace(a, '$1,'); //123,456,789

参考

正则表达式30分钟入门教程—墙裂推荐阅读

菜鸟教程正则表达式教程

正则表达式中的m修饰符1

正则表达式中的m修饰符2

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/362255.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hadoop namenode启动瓶颈分析

转载&#xff1a;http://blog.csdn.net/AE86_FC/archive/2010/08/26/5842020.aspx NameNode启动过程详细剖析 NameNode中几个关键的数据结构 FSImage Namenode会将HDFS的文件和目录元数据存储在一个叫fsimage的二进制文件中&#xff0c;每次保存fsimage之后到下次保存之间的所有…

Java 9 –终极功能列表

这篇文章将针对即将到来的Java 9版本进行更新&#xff0c;新增功能 &#xff08; 最新更新&#xff1a;2014年 9月9日 &#xff09; OpenJDK开发正在加快速度&#xff1a;2014年3月Java 8发布之后&#xff0c;我们预计将进入2年的发布周期。 据报道&#xff0c;Java 9将于2016…

2018.3.30 边框应用与导航栏设置

<!DOCTYPE html><html> <head> <meta charset"utf-8" /> <title></title> <style type"text/css"> /*制作三角形*/ #one{ width: 0px; …

centos 更改用户登录宿主机时间

chage -l username (查看用户登录时间&#xff1a;username为查看的用户) chage -M 90 username &#xff08;将用户登录主机的时间更改为90天&#xff09; 转载于:https://www.cnblogs.com/MUQINGFENG123/p/11075912.html

js中的作用域和作用域链

作用域就是变量与函数的可访问范围。在js中只有 全局作用域 和 函数作用域 &#xff0c;并没有块级作用域。 全局作用域 在所有函数外定义的变量、声明的函数就是全局作用域&#xff0c;在全部环境下都可以访问。 var a 111;function fn(){console.log(a); }fn(); // 打印了…

CryEngine3 引擎非商业用途将免费

CryEngine3引擎非商业用途将免费:8月发布 http://t.cn/hdEr45】Crytek日前宣布将在今年8月免费推出CryEngine3引擎的开发包&#xff0c;登录Crytek官网注册&#xff0c;签署保密协议保证不将CryEngine3用作商业用途&#xff0c;就可获得CryEngine3软件授权。Crytek官网上的一份…

vue打包后不使用服务器直接访问方法

根据官网打包执行npm run build 后dist文件夹打开的index.html 是空白 需要开启http服务器才能访问&#xff0c;以下是解决办法 1、找到config文件夹下的index文件 修改成 2、找到build文件夹下的until文件 修改成 然后执行npm run build重新打包下就ok了 更多专业前端知…

IntelliJ中的键盘快捷键

我上周参加了Hadi Hariri在JavaOne上的演讲。 他介绍了很多我不知道的IntelliJ键盘快捷键。 非常有用的谈话。 我在下面列出了一些最有用的。 Cmd-1&#xff1a;将焦点移到“项目”窗口 在此输入任何类名&#xff08;包括使用Camel Case&#xff0c;例如HW来查找HelloWorld&a…

OpenStack虚机网卡的创建过程

原文&#xff1a;https://www.sdnlab.com/20286.htmlOpenStack最基本和常用的操作就是启动虚机。虚机启动的过程中涉及很多内容&#xff0c;其中非常重要的一个环节就是创建并绑定虚机的虚拟网卡。虚机的创建和管理是Nova的任务&#xff0c;虚机网络的创建和管理是Neutron的任务…

js中的原型与原型链

js的学习有三座大山&#xff0c; 原型/原型链 、 作用域/闭包 、 异步/单线程&#xff0c;这三个知识点虽然基础但是入门时理解起来比较困难&#xff0c;本文先整理总结原型和原型链这一知识点。 1. 原型链怎么来的&#xff1f;对象的原型和function的prototype属性有什么关系…

线性表--算法设计题2.29

已知A&#xff0c;B和C为三个递增有序的线性表&#xff0c;现要求对A表作如下操作&#xff1a;删去那些既在B表中出现又在C表中出现的元素。试对顺序表编写实现上述操作的算法.&#xff08;注意&#xff1a;题中没有特别指明同一表中的元素值各不相同&#xff09;。C code: #in…

HTML5 audio 如何实现播放多个MP3音频

<audio>标签是HTML5中的新标签&#xff0c;定义声音用于嵌入音频内容&#xff0c;比如音乐或其他音频流。用的比较多音频格式是.mp3。 <audio>标签常用属性如下表 属性值描述autoplayautoplay添加该属性后&#xff0c;音频会自动播放controlscontrols设置后&…

Java代码中的典型错误

该页面包含在与我一起工作的人的Java代码中看到的最典型的错误。 静态分析&#xff08;出于明显的原因&#xff0c;我们使用查询无法捕获所有错误&#xff0c;这就是为什么我决定在此处列出所有错误的原因。 如果您要在此处添加其他内容&#xff0c;请告诉我&#xff0c;我们将…

windwos下ntp服务器配置 arm平台ntp客户端获取同步时间

项目需要使用同步时间&#xff0c;在arm-linux开发板上&#xff0c;移植了ntp客户端&#xff0c;查看了一些资料&#xff0c;最终发现使用windows自带的ntp服务器比较方便&#xff0c;而且很靠谱&#xff0c;使用配置了一番&#xff0c;已经能够正常使用 详细步骤&#xff1a; …

css 控制图片最大宽度

CSS 限制图片最大宽度 (本文来自本站原创&#xff0c;转载请务必注明出处&#xff01;)我们在制作一个网页的时候&#xff0c;经常要对一个区域里可能出现的图片的宽度进行限制&#xff0c;不然它可能会把页面撑得很烂很烂。如果你采用固定宽度&#xff0c;长度来设置的话&…

BOM(Browser Object Model)

BOM&#xff08;浏览器对象模型&#xff09;&#xff0c;提供了一系列操作浏览器&#xff0c;获取浏览器信息的接口。这些接口在平时的工作中会经常用到&#xff0c;例如当前页面的刷新&#xff0c;获取url的参数等等。 注&#xff1a;图片来自 http://www.dreamdu.com/javascr…

入门 IT 行业,该具备哪些技能?

对于刚开始进入IT的新人来说&#xff0c;“必备技能”往往意味着一个长长的、标有重要度的学习列表&#xff0c;但是过长的列表通常会导致新人不知如何开始学习&#xff0c;压力倍增。本文尝试列举出最重要的几个技能&#xff0c;也期望通过此列表能给新人一个比较明确的学习重…

实验七作业

Part 1:验证性实验 将line29&#xff1a;for(i0;i<N;i)改为while(!feof(fp)) // 从文本文件file1.dat中读取数据&#xff0c;找出最高分和最低分学生信息&#xff0c;并输出在屏幕上 #include <stdio.h> #include <stdlib.h>#define N 10// 定义一个结构体类型…

块级格式化上下文(Block Formatting Context)

CSS块级格式化上下文是块级盒子的一种能力&#xff0c;这种能力并不是直接通过css属性声明而获得的&#xff0c;而是添加css的一部分相关属性之后自动获得的能力&#xff0c;也就是说没有一个明确的属性就是生成块级格式化上下文的。 块级格式化上下文的能力就是让具有该能力的…

这是最后的讨论!

Pun打算……让我们讨论Java final 。 最近&#xff0c;我们广受欢迎的博客文章“编码Java时的十个微妙的最佳实践”在JavaWorld的摘要和链接中有了很大的复兴&#xff0c;并提出了一组新的评论。 尤其是&#xff0c;JavaWorld编辑对我们对Java关键字“ final ”的观点提出了质…