引言
对于正则表达式我想作为程序员肯定使用过它,那天书般的表达方式,我用一次就记住它了。这篇博客先介绍一些正则表达式的内容,然后介绍JavaScript中对正则表达式特有的改进。下面开始介绍正则表达式吧。
正则表达式是什么?
相信大家一定使用过windows的资源管理器搜索功能。例如我需要找出全部的txt文档,我们通常都会使用*.txt去进行匹配。在这里,*会被解释成任意的字符串。和通配符类�BC�,正则表达式也是用来进行文本匹配的工具,只不过比起通配符,它能更精 确地描述你的需求——当然,代价就是更复杂。
入门
假设我们现在需要匹配一个形式是这样的字符串(电话号码):025-85862979。在正则表达式中\d表示的是0-9任意的一个数字,那么使用最简单的方法我们可以使用下面这种正则表达式来进行匹配\d\d\d-\d\d\d\d\d\d\d\d。这种最简单的方法就是将每一个数字分割为\d进行表示。其实我们可以使用更加简洁的方式来表达。例如:0\d{2}-\d{8}。这里{2},{8}表示前面重复的次数。到此为止,\d是我们介绍的第一个元字符,下面我们将介绍更多元字符。
元字符
我们先来看一个例子:\ba\w*\b这个正则表达式匹配上面呢?它匹配以a开头的单词。先是某个单词开始处(\b),然后是字 母a,然后是任意数量的字母或数字(\w*), 最后是单词结束处(\b)。\d+匹配1个或更多连续的数字。 这里的+是和*类似的元字符,不同的是*匹配重复任意次(可能是0次),而+则匹配重复1次或更多次。\b\w{6}\b 匹配刚好6个字符的单词。
常见的元字符如下:
代码 | 说明 |
---|---|
. | 匹配除换行符以外的任意字符 |
\w | 匹配字母或数字或下划线或汉字 |
\s | 匹配任意的空白符 |
\d | 匹配数字 |
\b | 匹配单词的开始或结束 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结束 |
通过这个表格,我们看到正则表达式中常用的一些元字符的含义。对于^和$来说,有一点特别要注意:如果不使用^和$的话,对于\d{5,12}而言,使用这样的方法就只能保证字符串里包含5到 12连续位数字,而不是整个字符串就是5到12位数字。
字符转义
如果你想查找元字符本身的话,比如你查找.,或者*,就出现了问题:你没办法指定它们,因为它们会被解释成别的意思。这时你就得使用\来取消这些字符的特殊意义。因此,你应该使用\.和\*。当然,要查找\本身,你也得用\\.
例如:deerchao\.net匹配deerchao.net,C:\\Windows匹配C:\Windows。
重复
你已经看过了前面的*,+,{2},{5,12}这几个匹配重复的方式了。下面是 正则表达式中所有的限定符(指定数量的代码,例如*,{5,12}等):
代码/语法 | 说明 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
下面是一些使用重复的例子:
Windows\d+匹配Windows 后面跟1个或更多数字
^\w+匹配一行的第一个单词(或整个字 符串的第一个单词,具体匹配哪个意思得看选项设置)
字符类
要想查找数字,字母或数字,空白是很简单的,因为已经有了对应这些字符集合的元字符,但是如果你想匹配没有预定义元字符的字符集合(比如元 音字母a,e,i,o,u),应该怎么办?
很简单,你只需要在方括号里列出它们就行了,像[aeiou]就匹配任何一个英文元音字母,[.?!]匹配标点符号(.或?或!)。
我们也可以轻松地指定一个字符范围,像[0-9]代 表的含意与\d就是完全一致的:一位数字; 同理[a-z0-9A-Z_]也完全等同于\w(如 果只考虑英文的话)。
下面是一个更复杂的表达式:\(?0\d{2}[) -]?\d{8}。
“(”和“)”也是元字符,所以在这里需要使用转义。下面我们详细的解释下这段正则表达式。
这个表达式可以匹配几种格式的电话号码,像(010)88886666,或022-22334455, 或02912345678等。我们对它进行一些分析吧:首先是一个转义字符\(,它能出现0次或1次(?),然后是一个0,后面跟着2个数字(\d{2}),然后是)或-或空格中 的一个,它出现1次或不出现(?),最后是8个数字(\d{8})。
分支条件
不幸的是,刚才那个表达式也能匹配010)12345678或(022-87654321这样的“不正确”的格式。要解决这个问题,我们需要用到分枝条件。正则表达式里的分枝条件指的是有几种规则,如 果满足其中任意一种规则都应该当成匹配,具体方法是用|把不同的规则分隔开。听不明白?没关系,看 例子:
0\d{2}-\d{8}|0\d{3}-\d{7}这个表达式能匹配两种以连字号分隔的电话号码:一种是三位区号,8位本地号(如010-12345678),一种是4位区号,7位本地号 (0376-2233445)。
\(0\d{2}\)[- ]?\d{8}|0\d{2}[- ]?\d{8}这 个表达式匹配3位区号的电话号码,其中区号可以用小括号括起来,也可以不用,区号与本地号间可以用连字号或空格间 隔,也可以没有间隔。你可以试试用分枝条件把这个表达式扩展成也支持4位区号的。
\d{5}-\d{4}|\d{5}这个表达式用于匹配美国的邮政编码。美国邮编 的规则是5位数字,或者用连字号间隔的9位数字。之所以要给出这个例子是因为它能说明一个问题:使用分枝条件时,要注意各个条件的顺序。 如果你把它改成\d{5}|\d{5}-\d{4}的话,那么就只会匹配5位的邮编(以及9位邮 编的前5位)。原因是匹配分枝条件时,将会从左到右地测试每个条件,如果满足了某个分枝的话,就不会去再管其它的条件了。
分组(捕获性分组)
我们已经提到了怎么重复单个字符(直接在字符后面加上限定符就行了);但如果想要重复多个字符又该怎么办?你可以用小括号来指定子表达式(也叫做分组),然后你就可以指定这个子表达 式的重复次数了,你也可以对子表达式进行其它一些操作(后面会有介绍)。
(\d{1,3}\.){3}\d{1,3}是一个简单的IP地址匹配表达式。要理解这个表达式,请按下列顺序分析它:\d{1,3}匹 配1到3位的数字,(\d{1,3}\.){3}匹配三位数字加上一个英文句号(这个整体也就是这个分组)重 复3次,最后再加上一个一到三位的数字(\d{1,3})。
下面我们来看一下常用的分组语法:
分类 | 代码/语法 | 说明 |
---|---|---|
捕获 | (exp) | 匹配exp,并捕获文本到自动命名的组里 |
(?<name>exp) | 匹配exp,并捕获文本到名称为name的组里,也可以写成 (?'name'exp) | |
(?:exp) | 匹配exp,不捕获匹配的文本,也不给此分组分配组号 | |
零宽断言 | (?=exp) | 匹配exp前面的位置 |
(?<=exp) | 匹配exp后面的位置 | |
(?!exp) | 匹配后面跟的不是exp的位置 | |
(?<!exp) | 匹配前面不是exp的位置 |
在这里面,我会重点讲一下非捕获性分组。我们还是举个例子来看。前面的例子(\d{1,3}\.){3}会匹配一个三位数字加上一个英文句号。使用捕获性分组时,任何匹配这个分组的字符将会被捕获。这些符合条件的字符会被存储在内存中,以便下一次使用。其实,很多时候我们只是进行简单的匹配工作。默认的方式就造成了内存的浪费。因此,使用非捕获性分组,我们可以避免无谓的内存消耗。(?:\d{1,3}\.){3}。非捕获性分组和匹配无关,只是提升效率。
反义
有时需要查找不属于某个能简单定义的字符类的字符。比如想查找除了数字以外,其它任意字符都行的情况,这时需要用到反义:
代码/语法 | 说明 |
---|---|
\W | 匹配任意不是字母,数字,下划线,汉字的字符 |
\S | 匹配任意不是空白符的字符 |
\D | 匹配任意非数字的字符 |
\B | 匹配不是单词开头或结束的位置 |
[^x] | 匹配除了x以外的任意字符 |
[^aeiou] | 匹配除了aeiou这几个字母以外的任意字符 |
例子:\S+匹配不包含空白符的字符串。<a[^>]+>匹配用 尖括号括起来的以a开头的字符串。
JavaScript中的正则表达式
在JavaScript中使用RegExp来进行正则匹配。在JS中有两种方法来构建一个RegExp对象。通常优先的方法是使用正则表达式字面量,正则表达式字面量被包含在一对斜杠中。在JS中有3个标记可以在RegExp中设置,它们分别是字母g、i、m,它们可以直接添加到RegExp字面量的末尾。下面我们通过一个例子来看一下。
var regexp = /0\d{2}-\d{8}|0\d{3}-\d{7}/g;
下面我们来看一下g、i、m三个字母在JS正则表达式中的含义。如图:
创建一个正则表达式另一种方法是使用RegExp构造器。这个构造器接收一个字符串,并把它编译成一个RegExp对象。创建这个字符串要小心,因为反斜杠在正则表达式和在字符串字面量中有一些不同的含义。通常需要双写反斜杠及对引号进行转义。第二个参数是一个指定标记的字符串(g、i、m)。
参考文献
http://www.oschina.net/question/12_9507
https://msdn.microsoft.com/zh-cn/library/az24scfc.aspx
浅谈JavaScript中的正则表达式的更多相关文章
-
浅谈JavaScript中的正则表达式(适用初学者观看)
浅谈JavaScript中的正则表达式 1.什么是正则表达式(RegExp)? 官方定义: 正则表达式是一种特殊的字符串模式,用于匹配一组字符串,就好比用模具做产品,而正则就是这个模具,定义一种规则去 ...
-
浅谈JavaScript中的闭包
浅谈JavaScript中的闭包 在JavaScript中,闭包是指这样一个函数:它有权访问另一个函数作用域中的变量. 创建一个闭包的常用的方式:在一个函数内部创建另一个函数. 比如: functio ...
-
浅谈JavaScript中的null和undefined
浅谈JavaScript中的null和undefined null null是JavaScript中的关键字,表示一个特殊值,常用来描述"空值". 对null进行typeof类型运 ...
-
浅谈JavaScript中的内存管理
一门语言的内存存储方式是我们学习他必须要了解的,接下来让我浅谈一下自己对他的认识. 首先说,JavaScript中的变量包含两种两种类型: 1)值类型或基本类型:undefined.null.numb ...
-
浅谈JavaScript中闭包
引言 闭包可以说是JavaScript中最有特色的一个地方,很好的理解闭包是更深层次的学习JavaScript的基础.这篇文章我们就来简单的谈下JavaScript下的闭包. 闭包是什么? 闭包是什么 ...
-
浅谈JavaScript中的继承
引言 在JavaScript中,实现继承的主要方式是通过原型链技术.这一篇文章我们就通过介绍JavaScript中实现继承的几种方式来慢慢领会JavaScript中继承实现的点点滴滴. 原型链介绍 原 ...
-
浅谈JavaScript中继承的实现
谈到js中的面向对象编程,都有一个共同点,选择原型属性还是构造函数,两者各有利弊,而就片面的从js的对象创建以及继承的实现两个方面来说,官方所推荐的是两个相结合,各尽其责,各取其长,在前面的例子中,我 ...
-
【总结】浅谈JavaScript中的接口
一.什么是接口 接口是面向对象JavaScript程序员的工具箱中最有用的工具之一.在设计模式中提出的可重用的面向对象设计的原则之一就是“针对接口编程而不是实现编程”,即我们所说的面向接口编程,这个概 ...
-
浅谈JavaScript中的defer,async
引言 开始重读<<JavaScript高级程序设计>>一书,看到关于JavaScript中关于defer.async的部分.网上查询了点资料,觉得蛮好的.现在总结下. defe ...
随机推荐
-
chm手册显示已取消到该网页的导航
解决:在chm右键查看有没有解除锁定选项.1.右键单击chm文件,选择属性:2.在最下面点击“解除锁定”并确定后,再次打开chm,就正常了
-
iOS - UINavigationController
前言 NS_CLASS_AVAILABLE_IOS(2_0) @interface UINavigationController : UIViewController @available(iOS 2 ...
-
重装系统后删除Cygwin文件夹
1.右键点要删除Cygwin 文件夹,依次选属性-安全-高级-所有者-编辑,将所有者改为你的登录帐户,勾选下方“替换子容器和对象的所有者”. 2.在 属性-安全-高级对话框中选 权限选项卡,点更改权限 ...
-
Android中界面实现全屏显示的两种方式
在开发android的应用当中,我们会遇到将一些界面设置为全屏显示的格式,有两种实现的方法.其一是在Java代码中实现,其二是在配置文件中实现. 1. 在Java代码中设置 super.onCreat ...
-
Android Studio代码自己主动提示无效(not available in Power Save mode)
针对一位博友提的问题,我这边写出来,预计还是非常多人会碰到这个问题,可是不知道怎样解决的. 就是在设置了代码自己主动提示功能后,发现不生效的,怎样设置代码自己主动提示请戳这:Android Studi ...
-
jdk并发包 CopyOnWriteArrayList源代码分析
CopyOnWriteArrayList是jdk1.5并法包里面用于处理高并发下.读多写少的情况下.减少锁等待的集合类.以下对该类实现做一个简要的分析 1,首先CopyOnWriteArrayList ...
-
基于FPGA的VGA显示静态图片
终于熬到暑假了,记过三四周的突击带考试,终于为我的大二画上了一个完整的句号,接下来终于可以静心去做自己想做的事情了,前一阵子报了一个线上培训班,学学Sobel边缘检测,之前一直在学习图像处理,但是因为 ...
-
贪心-Wooden Sticks
先将火柴按照长度(或重量)优先排序,在不断遍历数组,找出其中重量(长度)递增子序列,并标记 Problem Description There is a pile of n wooden sticks ...
-
GitHub学习三-远程版本库更新与提交
1.远程版本库更新 一般来说,将本地与远程相关联之后,首先将数据从远程更新下来再上传比较好. 输入 git pull origin master 如果新建版本库的话勾选了初始化包含readme.md, ...
-
linux之磁盘配额(quota)使用方法(转)
1.什么是quota 简单的说就是限制用户对磁盘空间的使用量. 因为Linux是多用户多任务的操作系统,许多人共用磁盘空间,为了合理的分配磁盘空间,于是就有了quota的出现. 2.quota的用途 ...