历史版本
版本号 | 时间 |
---|---|
V1.0 | 2017.07.07 |
前言
在ios中很多情况下都需要进行专门的判断,比如判断输入的手机号是否正确,判断输入的邮箱格式是否正确,判断输入的字符串是否全是大写字母,判断输入的是否全部都是数字,等等。我们要让机器能够进行“自主”识别,就需要正则表达式的帮助,这里我们就说一下正则表达式的作用。
语法
要让及其读懂人写的代码,还是要依法而行的,太随心所欲,很明显你会机器搞晕,也就无法工作,下面我们就要看一下正则表达式的语法。
正则表达式也是由一些字符串组成的,但是他们的组成是有含义和规则的。正则表达式就是用一个“字符串”去验证另外一个“字符串”是否符合这个特征的式子,比如,表达式"ab+"描述的意义就是一个a和若干个b的组合,则ab、abbb、ab...b等都符合这个特征,下面我们就看一下更详细的语法。
一、单个字符的匹配
下面我们说一下单个字符的匹配,下面我们先看个例子。
- runoo+b,可以匹配 runoob、runooob、runoooooob 等,+ 号代表前面的字符必须至少出现一次(1次或多次)。
- runoo*****b,可以匹配 runob、runoob、runoooooob 等,*** 号代表字符可以不出现,也可以出现一次或者多次(0次、或1次、或多次)。
- colou?r 可以匹配 color 或者 colour,? 问号代表前面的字符最多只可以出现一次(0次、或1次)。
构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与运算符可以将小的表达式结合在一起来创建更大的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。
正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为"元字符")组成的文字模式。模式描述在搜索文本时要匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。
二、普通字符
普通字符包括没有显示指定为元字符的所有可打印字符,这包括所有的大写字符、小写字母、所有数字、所有标点符号和一些其他的符号。
三、非打印字符串
非打印字符串也是正则表达式的组成部分,下表列出了表示非打印字符的转义序列。
字符 | 描述 |
---|---|
\cx | 匹配由x指定的控制字符,例如:\cM匹配一个Conrtrol -M或回车符,x值必须为A-Z或a-z之一,否则,将c视为一个原义的'c'字符。 |
\f | 匹配一个换页符,等价于\x0c和\cL。 |
\n | 匹配一个换行符,等价于\x0a和\cJ。 |
\r | 匹配一个回车符,等价于\x0d和\cM。 |
\s | 匹配任何空白字符,包括空格、制表符、换页符等,等价于[\f\n\r\t\v]。 |
\S | 匹配任何非空白字符,等价于[^\f\n\r\t\v]。 |
\t | 匹配一个制表符,等价于\x09和\cl。 |
\v | 匹配一个垂直制表符,等价于\x0b和\cK。 |
四、特殊字符
所谓的特殊字符,就是一些有特殊含义的字符,例如*(星号),简单的说就是表示任何字符串的意思,如果要查找字符串中的***符号,则需要对*进行转义,即在其前面加一个\,runo\*ob匹配runo*ob。
许多元字符都要求在匹配它们的时候要特别对待,若要匹配这些特殊字符,必须首先使字符“转义”,即,将\放在它们前面即可。很多情况如下表所示。
特别字符 | 描述 |
---|---|
$ | 匹配输入字符串的结尾位置,如果设置了RegExp对象的Multiline属性,则$也匹配了'\n'或'\r',要匹配$字符本身,请使用$。 |
() | 标记一个子表达式的开始和结束位置,子表达式可以获取供以后使用,要匹配这个字符,请使用(和)。 |
* | 匹配前面的子表达式零次或多次,要匹配*字符,请使用\*。 |
+ | 匹配前面的子表达式一次或多次,要匹配+字符,请使用\+。 |
. | 匹配除换行符\n之外的任何单字符,要匹配.,请使用\.。 |
[ | 标记一个中括号表达式的开始,要匹配[,请使用\[。 |
? | 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符,要匹配?字符,请使用\?。 |
将下一个字符标记为特殊字符,或原义字符、或向后引用、或八进制转义符,例如:'n'匹配字符'n',‘\n’匹配换行符,序列‘\\’匹配""。 | |
^ | 匹配输入字符串的开始位置,除非在方括号表达式中使用,此时,它表示不接受该字符集合,要匹配^字符本身,请使用^。 |
{ | 标记限定符表达式的开始,要匹配{,请使用\{。 |
竖线 | 指明两项之间的一个选择,要匹配竖线,请使用\加上竖线。 |
五、限定符
限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足的匹配,限定符一共有六种。
- *
- ?
- {n}
- {n,}
- {n,m}
具体的限定内容其实前面我们都说过几种了,下面我们就继续说下边的,看下表。
字符 | 描述 |
---|---|
* | 匹配前面的子表达式零次或者多次,例如:zo*能匹配“z”以及“zoo”,等价于{0,}。 |
+ | 匹配前面的子表达式一次或者多次,例如,'zo+'能匹配’zo‘以及'zoo',但不能匹配'z',+等价于{1,}。 |
? | 匹配前面的子表达式零次或者一次,例如'do(es)?'可以匹配'do'或’does‘,其等价于{0,1}。 |
{n} | n是一个非负整数,匹配确定的n次,例如,'o{2}'不能匹配’Bob‘中的’o‘,但是能匹配'food'中的两个o。 |
{n,} | n是一个非负整数,至少匹配n次,例如’o{2,}‘不可以匹配'Bob'中的'o',但能匹配'foooooood'中的所有o,’o{1,}‘等价于'o+',’o{0,}‘则等价于’o*‘。 |
{n,m} | m,n均为非负整数,其中n<=m,最少匹配n次,最多匹配m次,例如'o{1,3}'将匹配'fooooood'中的前三个o,’o{0,1}‘等价于'o?',注意在逗号和两个数之间不能有空格。 |
六、定位符
定位符使您能够将正则表达式固定到行首或者行尾,它们还能使您能够创建这样的正则表达式,这些表达式出现在一个单词内,在一个单词的开头或者一个单词的结尾。^
和$
分别指字符串的开始与结束,span class="marked">\b描述单词的前或后边界,span class="marked">\B表示非单词边界。
关于正则表达式的限定符如下表格所示。
字符 | 描述 |
---|---|
^ | 匹配输入字符串开始的位置,如果设置了RexExp对象的Multiline属性,^还会与\n或\r之后的位置匹配。 |
$ | 匹配输入字符串结尾的位置,如果设置了RexExp对象的Multiline属性,^还会与\n或\r之前的位置匹配。 |
\b | 匹配一个字边界,即字与空格间的位置。 |
\B | 非字边界匹配。 |
注意:
不能将限定符与定位点一起使用。由于在紧靠换行或者字边界的前面或后面不能有一个以上位置,因此不允许诸如 ^* 之类的表达式。
若要匹配一行文本开始处的文本,请在正则表达式的开始使用 ^ 字符。不要将 ^ 的这种用法与中括号表达式内的用法混淆。
若要匹配一行文本的结束处的文本,请在正则表达式的结束处使用 $ 字符。
若要在搜索章节标题时使用定位点,下面的正则表达式匹配一个章节标题,该标题只包含两个尾随数字,并且出现在行首。
/^Chapter [1-9][0-9]{0,1}/
- 匹配字边界稍有不同,但向正则表达式添加了很重要的能力。字边界是单词和空格之间的位置。非字边界是任何其他位置。下面的表达式匹配单词 Chapter 的开头三个字符,因为这三个字符出现字边界后面。
/\bCha/
- \b 字符的位置是非常重要的。如果它位于要匹配的字符串的开始,它在单词的开始处查找匹配项。如果它位于字符串的结尾,它在单词的结尾处查找匹配项。例如,下面的表达式匹配单词 Chapter 中的字符串 ter,因为它出现在字边界的前面。
/ter\b/
- 下面的表达式匹配 Chapter 中的字符串 apt,但不匹配 aptitude 中的字符串 apt。字符串 apt 出现在单词 Chapter 中的非字边界处,但出现在单词 aptitude 中的字边界处。对于 \B 非字边界运算符,位置并不重要,因为匹配不关心究竟是单词的开头还是结尾。
/\Bapt/
七、选择
用圆括号将所有选择项括起来,相邻的选择项之间用|分割,但用圆括号会有一个副作用,是相关的匹配会被缓存,此时可用?:放在第一个选项前来消除这种副作用。其中 ?: 是非捕获元之一,还有两个非捕获元是 ?= 和 ?!,这两个还有更多的含义,前者为正向预查,在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串,后者为负向预查,在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。
八、反向作用
对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。缓冲区编号从 1 开始,最多可存储 99 个捕获的子表达式。每个缓冲区都可以使用 \n 访问,其中 n 为一个标识特定缓冲区的一位或两位十进制数。可以使用非捕获元字符 ?:、?= 或 ?! 来重写捕获,忽略对相关匹配的保存。反向引用的最简单的、最有用的应用之一,是提供查找文本中两个相同的相邻单词的匹配项的能力。以下面的句子为例。
Is is the cost of of gasoline going up up?
上面的句子很显然有多个重复的单词。如果能设计一种方法定位该句子,而不必查找每个单词的重复出现,那该有多好。下面的正则表达式使用单个子表达式来实现这一点。
var str = "Is is the cost of of gasoline going up up";
var patt1 = /\b([a-z]+) \1\b/;
document.write(str.match(patt1));
后记
未完,待续~~~