GG资源网

关于正则表达式 大于等于100 或者小于100的正则表达式

问题描述:

问题: 用正则表达式表示大于等于100 或者小于100的所有数字,包括小数

我写的有点问题/^[0-9]{3}[0-9.]{0,}$ 如果我写啦100.2.3这个就验证不出来

谢谢

网友观点:

这次明白了!!

试试^[1-9]\\d{2,}[.]?\\d*

[quote]用正则表达式表示大于等于100 或者小于100的所有数字,包括小数 [/quote]
是不是可以理解为用正则表达式表示所有的数字,包括小数 :( 这样写的意义是什么?
随手写了一个,不知道满足不? ^\\d{2,3}(.\\d+)*

^\\d{3}(.\\d+)*

问题都描述不清楚,什么是正确的数字?整数?败给你了。。。。。。 :x

挣点分还真是不容易呀。 :?

大于等于100以上的整数 可以用这种方式来表达^\\d{3,}
包含小数可以用 ^\\d{3,}(.\\d+)*

^((\\d*[1-9]\\d{2})|(\\d{1,2}[.]?\\d*)|([-]\\d*[.]?\\d*))$

大于等于100,或者小于100的表达式就在这边了

正则表达式基础总结

一. 概念

首先需要接受正则的概念,它是用来寻找文本的一种规则,简单的文本检索,比如字符串查找strpos,只是简单的查找某一串字符的出现,只要稍微变动下需求,比如要查找这样5个字符,前面两个是数字,后面3个是字母,且忽略大小写,如果单纯用字符串查找等方法做,显得很麻烦,而用正则表达式就无比简单了。正则很强大很灵活,当然灵活的东西一般规则也有点多。在平常生活中,不知不觉会用到正则类似的东西,比如搜F盘下的所有文本文件:*.txt,或者在某些编辑器如Sublime Text,对正则超找提供了支持,又或者在linux命令中也经常用到:find . -name '*.log' -print查找当前目录下扩展名为log的文件,或者查询日志时cat 2015-10-18-log |grep 'show_list'(这个不是,只能说类似):打印出记录了show_list接口的行等等,以及Apache的RewriteRule对访问链接的控制,这些都类似或者就是正则表达式的应用。

在php中,用来支持正则的有三种引擎:preg、ereg、mb_ereg,所谓引擎简单理解就是底层一些对php在进行正则匹配查找时进行支持的库和接口,不同的库有不同的名字,现在用的多是preg,它在功能和速度上要强于其余两者。preg引擎(或者说套件),即“Perl的正则表达式”(Perl Regular Expression),源于某大牛对当时的ereg套件在性能上的不满,想做一个更好的库,于是查阅Perl处理正则的源代码,但是在他之前另外一大牛,也遇到过这个问题,此大牛(后者)研究了一下Perl正则源代码,觉得繁琐复杂,于是自己写了一套兼容Perl的正则库PCRE(Perl Compatible Regular Expression),编写清晰,效率出众,文档完备,然后前一位大牛将其改写到php中,就成了preg,一直慢慢改进到今天。所以preg兼容PCRE,PCRE兼容Perl的正则,preg就是Perl正则的亲戚,以上为历史。

二. 使用:

  一个简单的正则表达式示例:'/abc/',表示匹配一个字符串中的abc三个字符,完全等价于普通的字符串查找方法,正则就是一个字符串,只是特殊的符号有特殊的含义而已,而一般将这串表示正则的字符串称为:模式(pattern)。

1. 定界符

  在定义一个正则表达式时,首先要有定界符,表示表达式从这儿开始,到那儿结束,最常用的是/,如匹配abc的'/abc/',从a开始,到c结束。在php中,还可用其他的,比如#、!、{}(左边用{,右边用})等,全凭个人习惯。

2. 原子

  原子是正则表达式中最基本的单位,细分为5类,俺将伴随它的功能来记录。

  首先,可以用最普通的字符作为原子,如a、B、c、1、2、_等

'/9527/'

'/misson failed/'

'/PHP_VERSION/'

  一些特殊字符和元字符(metacharacter)也可以,任何一种符号都能在模式中使用,前提是别跟它自己的表示特殊含义的符号相冲突,前面说过,正则很灵活很强大,强大在于有这些特殊含义符号的辅助(有什么特殊作用后面再说),如果正则中要匹配这个在这里有特殊含义的符号,需要转义(escape),很好理解,就跟双引号字符串中有双引号也要转义一样。这些特殊符号包括.、*、?、+、‘、"、\\ 、/ 等等,其实单引号、双引号有时不必转,全看你写的表达式用的是单引号字符串还是双引号字符串,在php中为避免出错写正则一般用单引号字符串。还有就是别跟自己的定界符冲突,否则系统以为表达式提前结束而出错。

'/a\\.b\\?c\\+/'

'/ab\\/123/'

  非打印字符作原子,非打印字符泛指空白字符,即空格、水平制表符\\t、垂直制表符\\v、回车符\\r、换行符\\n等,注意此处易埋bug,php用单引号字符串,减少出错

'/\\r\\n/'

  前面说过,可以匹配一般的单个字符,如9527,9后面接着一个5,再接着一个2,然后是7,现在匹配的并不限于这几个数字,比如我要匹配两个数字,只要是数字就行,对于这种带有通用性质的字符,正则也有表示某一类字符的的表示形式,比如表示数字用\\d,表示一个0到9的十进制数字,而\\D(大写形式)表示非十进制数字,\\w表示匹配一个单词,在php的正则流派里边,单词的定义是大写字母A-Z,小写字母a-z,数字0-9以及下划线_,相应的\\W大写形式表示相反的意义。

'/\\d\\d/' // 匹配两个数字

'/\\D/' // 匹配一个除数字之外的任意字符

'/\\w/' // 匹配一个词

'/\\W/' // 匹配一个除了词的任意字符

'/\\s/' // 匹配一个空白字符

'/\\S/' // 匹配一个非空白字符

3.元字符

  元字符就是有特殊意义的字符,如*、+、?、. 、|、^、$等,一般不能单独出现,只有在修饰它前面的一个(或一些)原子时才表现出它自己的特殊含义,也就是说,它要配合上面说的原子使用才有意义。它有特殊意义,但就是要匹配它时,就得使用转义符\\了,转为普通字符。

?:量词,有或者没有

现在要匹配一个单词意思颜色,有两种写法,colour或color,中间的u要么有1个,要么没有,元字符?就适合,而且,如果没有加括号限制,元字符量词这类元字符只对位于它前面一个原子起作用,这里?只作用于u

'/colou?r/'

+:量词,一个或多个

  比如匹配一个或多个数字,注意元字符修饰的原子有可能是个序列,但未加括号限制只对一个有效

1

'/\\d+/'

*:量词,0个、1个或多个,即任意数量

'/\\d*/'

  区间:规定重复出现次数

  前面的次数限制毕竟比较死板,来个活的,区间用一对{}表示,{n}表示出现n次,{n,}表示大于或等于n次,{m,n}表示至少出现m次,至多出现n次,最好m小于n,别故意为难系统~

'/auth{0,1}/' // 出现0次到1次,即?

'/auth{1,}/' // 至少出现1次,即+

'/auth{3}/' // h要出现3次

  匹配任意字符

.,点号,匹配任意字符,在php中,默认情况下除了换行符,它可以匹配任意任意一一个字符,另外一种情况下,它就真的匹配任意字符,包括换行符,后面再说。

  多选结构

|,表示或,依靠它可以生成一个多选分支,需要注意的是|在正则中优先级最低,,下面的不是|作用的不是左右的r和c,而是|左右的子表达式,哪怕把一个表达式写成'/\\d+\\s*abc{2,5}|ack?\\d/',它仍作用于它前面和后面的子表达式\\d+\\s*abc{2,5}和ack?\\d,只要没有加括号限制

'/color|colour/' // 匹配color或colour

4.字符组

  匹配若干字符之一,现在要匹配abc中任一个字符,可以这样:[abc],包在一堆中括号里边,加入要匹配大写A到大写Z任一个字符,可以这样:[A-Z],中间一个连字符在字符组里边就成了有特殊意义的元字符表示从什么到什么,,其他还有数字[0-9],或者只是数字、字母的部分值:[2-5]、[c-h],有几个需要注意的地方:

1. 连字符-只有在字符组内部,且在两个字符之间才被认为是有效的元字符,出了字符组跟a一样是普通字符;

2. 如果字符组内部确实需要匹配-,最好将它放在字符组内最前面,如[-a-z],匹配小写字母或-,在php中也可以将它放在最后,如[c-k-](居然没报错-_-#),但放在最前面还是最保险;

3. 对于系统不认可的由-标识的顺序字符,对于php会报Compilation failed警告,如[a-9]、[9-0]

4. 字符组的顺序一般为从小到大,不能[9-0],大小写一般分开写[A-Za-z],但在php中,至少俺这个5.5版本可以大小写混合写[A-z],表示匹配从A到Z和a到z的字母,不提倡这样做,其他语言流派肯能不支持

'/C[EFIMT]O/'

'/[A-Za-z0-9_]/' // 相当于\\w,表示单词

'/[a-z]+/' // 匹配一个或多个小写字母

5.排除型字符组

  前面是匹配任意一个[]内的字符,现在恰好相反,不匹配任意一个字符[]内的字符,如[^a-z]:不匹配任意一个小写字母,在字符组内最前面加^表示取反。一个有意思的例子:

'/abc[^ABC]/'

字符串1: 'abcK'

字符串2: 'abc' // 匹配?

  字符串1很显然,字符串2匹配吗?注意字符组:它匹配未出现的字符。这里abc后面要跟一个除A、B或C的字符,但是不能没有,这便是字符组的坑。

6.单词边界

  有时为了匹配一个完整单词,一般单词给人印象是左右带有空格,专门有一个表示单词的这种边界元字符\\b,注意它并不匹配一个空格,而是一个位置,所以单独的'abc'也被看作一个单词,虽然它左右并没有空格,关于匹配位置后面再详说。但是正则中,至少目前对单词的定义还没那么强大,就是大小写字母、数字加下划线,跟单词边界相反的就是\\B,只要不是单词边界都能匹配

'/\\b\\w+\\b/' // 匹配一个单词

'hello world' // 匹配hello(只匹配一次的话)

'abc' // 匹配abc

  括号限定

  括号的第一个强大功能,是限定元字符的作用范围,将表达式分成一个个子表达式,如'/col(ou)?r/',加了括号后,?元字符作用的对象是ou而不再只是u,'/abc|def/'指的是匹配abc或者def,但a(bc|de)f匹配的是abcf或者adef,类似编程语言括号运算符,括号内是一个小的单元,相当于一个大原子,当然它还有一个重要作用:分组,后面再说。

7.行的开头与结尾

  每一行字符串都有一个开头和结尾,开头和结尾指一个位置,虽然我们在描述一串字符串会说以...结尾,但正则中不指具体字符,匹配的是位置。比如'/^a.+/',匹配以a开头的字符串,^表示开头,$表示结尾,下面是几个值得注意的例子

'/^/'// 匹配一个行开头,只要是一行字符串都有开头,哪怕空字符串,无实际意义

'/^$/' // 匹配一个行开头,紧接着是行结尾,即匹配一个空行

'/^hello$/' // 匹配以hello开头的字符串,随后改行便结尾,即匹配只有hello字符串的行,该行再无其他字符

'/^hello.*hello$/' // 匹配一个行开头,接着是hello,接着可能是若干其他字符,然后是hello,紧接着是行结尾,即匹配一个一hello开头,hello结尾,中间有若干字符的字符串

注意在默认情况下,脱字符^和美元符号$表示匹配一个字符串的开头和结尾,比如"hello",结尾在紧挨着o的右边,那么"hello\\nabc"(在php的双引号字符串中,\\n是元序列,表示换行符,但php的单引号字符串\\n只是普通字符,一个\\一个n,特此说明)该看做一行还是两行呢?答案是,在preg中,默认情况下,仍被看做一行,它的结尾是紧挨着c的右边,可以验证下

<?php

$pattern = '/hello$/'; // 以hello结尾

$subject = "hello\\nabc"; // 匹配字符串的结尾,而不是逻辑行的结尾

preg_match($pattern, $subject, $match);

echo 'match=><pre>';

var_dump($match); // 无匹配内容

  我们把"abc\\n"称为一个逻辑行,把"abc\\ndef\\n"称为有两个逻辑行,因为逻辑上它是有两行字符串的,但preg默认不匹配多个逻辑行(可能是坑),管你几个换行符就当一行字符串看,$直接匹配到这个字符串最后一个位置。那么php的正则能不能匹配多个逻辑行呢?当然行,要用到模式修饰符,后面再说。

  除了以^表示行开头,$表示行结尾,在preg中,\\A也表示开头,\\z和\\Z都表示结尾,不同的是\\Z能匹配到最后的换行符,而\\z不行。

8. 分组和捕获

  一个简单的例子,匹配以单引号或双引号开头的字符串,结尾需要是对应的双引号或单引号(中间不存在转义过的双引号或单引号)

'/["\\'].*["\\']/'

  如果是上面那样,第一个字符组匹配了双引号,是无法保证第二个字符组匹配相同的双引号,即现在的要求是,前面那个字符组匹配了什么,后面那个字符组也需要匹配相同的字符,不是给一个相同的正则表达式就行。

  前面说过括号的第一大作用,限定某些元字符的作用范围,括号的另一大作用就是分组捕获,这是正则的特性。比如'/ab(cd)ef(gh)ij/',有两个括号,preg引擎会对每个括号中匹配到的文本进行记录,以左括号由左往右数,以数字编号,\\1记录的是第一个左括号所在的里边的内容,\\2记录第二个左括号所在的里边的内容,第n个左括号对应\\n,preg最多可记录4096个(强大!),这里\\1对应cd,\\2对应gh。括号起到了分组的作用,而类似\\1、\\2...\\n称为反向引用。注意:引用的是正则匹配到的文本,而不是引用的正则表达式

$pattern = '/(\\w)(\\d)(.*)/'; // 匹配一个词,一个十进制数字和若干任意字符

$subject = 'a57h';

preg_match($pattern, $subject, $match);

echo 'match=><pre>';

var_dump($match);

  结果:

preg_match方法将捕获的文本放在$match参数中,数组索引的1、2、3对应的元素分别是捕获到的\\1、\\2、\\3三个分组文本(索引0列出的是整个表达式匹配到的文本)。

  对于括号嵌套的,只看左括号的相对顺序,比如'/(abc(def)g(hij))(k)/',有效的左括号为4个,\\1对应abc的左括号整个括起来的内容(abcdefghij),也包括里边嵌套括号匹配的内容,\\2对应def,\\3对应hij,\\4对应k。

  所以对于上边引号对应的例子可以是这样的:'/(["\\'].*)\\1/',后面的字符要与第一个匹配到的文本一致(注意不是模式一致)。

  但是新的变种又来了,有的想分组捕获,但有的只想分个组,限定下范围,不想捕获,?:来了,(?: ... ),在分组的括号最前面添加问号冒号,就表示取消文本捕获。因此对于'/(?:abc(de)fg(?:hij))/',\\1捕获的是de,没有\\2。

  除了数字捕获(\\后面跟数字来标识捕获内容),还可使用命名捕获,即给捕获到的文本取名字,用法(?P<name>...),对括号添加?P<name>,name是取的名字,有的书上写着(?P=name),5.5亲测不行。

$pattern = '/\\w(?P<key1>\\w\\w)\\s+(?P<key2>\\d+)/';

$subject = 'abcd 233';

preg_match($pattern, $subject, $match);

echo 'match=><pre>';

var_dump($match);

  结果:

  在php的命名捕获时,把原来数字形式的捕获也记录了,key1与\\1对应,key2与\\2对应,反正多一种不嫌多。

  捕获的另一个巨大的用处,就是在替换操作时,对匹配的文本的引用,比如现在有表达式 '/123(\\d\\d\\d)ok([a-z][a-z])end/',括号捕获到三个数字和两个小写字母,我们想提取出来,怎么办,就preg来说,使用简单的替换方法:preg_replace。一个例子

$pattern = '/123(\\d\\d\\d)ok([a-z][a-z])end/';

$subject = '123233okhiend';

$replacement = '$1---$2'; // 在替换字符串中,对捕获到文本的引用

$ret = preg_replace($pattern, $replacement, $subject);

echo 'ret=><pre>';

var_dump($ret);

  括号捕捉到了233和hi,如果是反向引用我们知道是\\1和\\2,替换的字符串$replacement中,使用$1、$2来捕捉它,注意\\1、\\2是用在原始的正则表达式中的,这里是替换字符串中,当然,替换操作的是字符串的副本。

  结果:

  如果用命名捕获来操作,使用对应的$name来引用,亲测貌似不行,估计是怕跟上下文中的变量相冲突,但是上面说了,在命名捕获时,数字索引仍然是有效的,所以在命名捕获时,我们仍然可以再替换字符串中通过$1来引用匹配到的文本。

  一个需要注意的问题:假设我捕获到了第1组,替换文本是'$15',1后边又跟着个数字,容易出错,为提高解析效率,可使用{}将数字括起来,如'${1}5',另,这对命名捕获仍无效。

9. 环视

  前面的行开头、结尾是对位置的匹配,环视( lookaround)也是对位置的匹配,对于这种位置匹配,可能一个更熟悉的名字是:零宽断言。^、$、\\A、\\Z、\\b、\\B都算零宽断言,包括环视结构,当然行开头和结尾也多称为锚点。比如俺曾做的一个小项目中,有这样的需求,使用一个别人搭建的框架,每一个model类处理一张表,表名根据model类的类名确定,它的类名一般是这样的class externalLinks extends Model{...},子类名是这样externalLinks,它的表名是gw_external_links,gw_不说,从externalLinks到external_links需要在左边是小写字母,右边是大写字母的地方插一个_,再转小写,而且类名不一定只有这样的,比如abcDefGhi,可能是3个大小写单词,个数不确定,用字符串的替换显得比较麻烦,因为个数不确定,用正则轻而易举就解决了。凡是这种某地方的左边是啥,右边是啥,明显的位置要求的,都可以用环视试一下。环视分为四种:

  肯定顺序环视:(?=...),匹配某个位置,它的右边是...

  肯定逆序环视:(?<=...),匹配某个位置,它的左边是...

  否定顺序环视:(?!...),匹配某个位置,它的右边不是...

  否定逆序环视:(?<!...),匹配某个位置,它的左边不是...

  不看...就是环视的符号定义,顺序、逆序的区别在于一个从左往右看,一个从右往左看。环视在位置检测时非常有用。例如现在要匹配abc,它的右边必须是数字,可以这样

'/abc(?=\\d)/'

  说说俺自己上面那个问题,找到左边是小写字母,右边是大写字母的位置,可以这样

'/(?=[A-Z])(?<=[a-z])/'

  如果左右两边都需要检测的,像这种,顺序环视跟逆序环视的左右顺序的顺序不用管,哪个放左边哪个放右边都行(等价于'/(?<=[a-z])(?=[A-Z])/')。一般来说逆序环视放左边,顺序环视放右边,一个好习惯是以位置为中心,想象这个位置左边应该有什么,右边应该有什么。上面的模式找到位置了用_替换(实际是插入)掉问题基本就解决了。再比如

$pattern = '/\\w+(?=\\d)/';

$subject = 'abcd 233';

preg_match($pattern, $subject, $match);

echo 'match=><pre>';

var_dump($match);

  结果:

  想想为啥?匹配一个或多个词,它的右边必须是数字,只有'23'符合,它的右边恰好为数字,2的前面是空格,不属于\\w范围,而'233'的后面啥都没有。

  注意:只匹配位置,不匹配实际文本,这个有时在多次匹配时有很大区别。

  对于单词边界符\\b,也可用环视写出来,单词的开始边界是左边非单词右边为单词:(?<!\\w)(?=\\w),单词的结束边界是左边为单词右边非单词:(?<=\\w)(?!\\w),合在一起就是:(?<!\\w)(?=\\w)|(?<=\\w)(?!\\w)(|,或的左右表达式是整体,它的优先级最低)。

10. 占有优先 vs 忽略优先

  标准量词都是匹配优先的,如*、+、?以及区间量词{m,n},它们总是在自己的范围内尽可能多的匹配字符,对于{m,n}(m<n)有n个的话绝不止匹配m个就完事儿。例如

$pattern = '/\\w+(?=\\d)/';

$subject = 'hello123';

preg_match($pattern, $subject, $match);

echo 'match=><pre>';

var_dump($match);

  结果:

  上例在匹配单词时总是尽可能匹配最多,所以单看\\w+会一直匹配到字符串结尾3处,但随后的环视检查出现右边不是一个数字(什么都没有),于是交还一个词,再看看右边是不是数字,这下是了(hello12)然后就匹配成功返回,这里有一个回溯的过程(下一篇写写),不细纠结,有的书称这种匹配优先为贪婪模式,即标准量词默认都是贪婪的,尽可能多的去匹配的,那么与之对应的就有非贪婪模式。

  在量词后面加个问好,表示非贪婪模式,即忽略优先,如*?、+?、??、{m,n}?,非贪婪模式下的量词总是尽可能匹配少的字符,还是上面那个例子,如果把$pattern改为下面呢?

$pattern = '/\\w+?(?=\\d)/'; // 忽略优先

  匹配的结果是'hello',过程是首先+?使得\\w每匹配一个词就检查下右边是不是数字,是的话匹配就此停止,返回结果,要保证匹配到的字符最好嘛,不是的话继续匹配,直到右边是数字便立即停止返回。忽略优先可以提前返回结果,当然可能不是最优的,提高匹配速度(下一篇再总结下)。

  有木有倔强的不交还的列?当然有,这就是占有优先,它在标准量词后面加一个+,如*+、++、?+、{m,n}+,把上面的例子再改改,有意向不到的结果-_-#

$pattern = '/\\w++(?=\\d)/'; // 占有优先

  记住占有优先的特点:不交还!\\w+一直匹配到hello123结尾,发现之后啥都没有,失望至极,然后停止匹配,报告匹配失败了,没错这次居然是匹配失败了!占有优先仍属于匹配优先,尽可能多的去匹配,只是匹配到最后如果发现某条件不符,不好意思,他不服,直接停止。所以占有优先可以提前报告失败,提高匹配速度

  忽略下占有优先的脾气,来看一个新东西:固化分组。表示方式:(?>...)(它应该属于分组捕获的,俺觉得放这儿更好),同占有优先功能一样,它也是优先匹配,并且不交还。所以再把上面的$pattern改为这个样子,也是匹配失败滴。

$pattern = '/(?>\\w+)(?=\\d)/'; // 固化分组

11. 模式修饰符

  模式修饰符(pattern modifier),放在模式的最后面,结束定界符之后,如'/....../imx',i、m、x表示不同的修饰符,可以一次使用多个。模式修饰符是对正则表达式整体效果起一个调节作用。

i:匹配时不区分大小写,如'/abc/i',对匹配到的abc任一个大小写都可;

m:将字符串视为多个逻辑行,还记得前面说匹配一行字符串的开头^和结尾$吗?默认preg将字符串视为一行,哪怕里边有有效的换行符,如果加了修饰符m,将带匹配字符串按照换行符分行,这些行称为逻辑行,^匹配每一个逻辑行的开头,$匹配每一个逻辑行的结尾;

s:还记得前面说的匹配任一字符的元字符 . (点号)吗?preg默认情况下点号匹配任一个字符,除了换行符,那么加了s修饰符,点号就连换行符也不拒绝了;

x:这个修饰符对于复杂的正则表达式非常有用,因为它可以在正则中添加注释!!!而且它会忽略正则中的空白符,当然,也包括换行,为了说明乱举一例:

// 使用x修饰符

$pattern = '/(\\w+ \\d)

(?: # 这里匹配啥啥啥

"\\w" | "\\d"

| # 这里应当这么理解那啥

[-A-Z]+ # 这里你自己猜

)/x';

$subject = 'wcwieu2832z28';

preg_match($pattern, $subject, $match);

e:它在特定的地方有用,即preg_replace方法中,preg的preg_replace方法原型如下

mixed preg_replace(mixed $pattern, mixed $replacement, mixed $subject [, int $limit = -1 [,int &$count ]])

  第二个参数$replacement,会将匹配到文本替换为它,使用e修饰符,$replacement不仅可以用简单的文本,不仅可以对捕获到的文本进行$1式的引用,更流弊的是,可以写php代码,以字符串的形式(有点eval的感觉),例

$ret = preg_replace('/\\d([A-Z]+)/e', 'strtolower("$1")', '5BBC');

echo 'ret=><pre>';

var_dump($ret);

  可是当俺准备看结果时,报错:The /e modifier is deprecated, use preg_replace_callback instead,纳尼!模式符e被弃用了,让用preg_replace_callback这个方法,它使用一个会调函数(异步调用)来处理匹配到的结果,显然比把代码直接堆在字符串里好多了,具体怎么用可以参考手册。

D:设定了此修饰符的话,模式中的$只会匹配字符串的结尾(EOS,End Of String),而不是EOS前面的换行符,即不会看做多行。但如果设定了m修饰符将忽略此选项;

U:反转了 * 跟 *? 的含义,原来的匹配优先变为忽略优先,原来的忽略优先变为匹配优先。除了让人更加晕菜以外,好像没个鸟用。

  最后,还有个文本模式,不是模式修饰符,表示方式 \\Q ... \\E。

  假如我们就是想匹配一段文本,但是里面夹杂了很多元字符,转义后看起来会很乱。就可以使用 '/\\Q$*.?|/\\E/',只是举个极端的例子,\\Q与\\E之间的字符,preg一律把它当做普通字符处理,免去转义之劳。当然也可以手动转义,更加可以用preg_quote来将这个没有带\\Q和\\E的表达式转为一个转义后的表达式。

三. 基本语法描述

1.正则基础

正则基础

元字符 描述

\\ 将下一个字符标记符、或一个向后引用、或一个八进制转义符。例如,“\\\\n”匹配\\n。“\\n”匹配换行符。序列“\\\\”匹配“\\”而“\\(”则匹配“(”。即相当于多种编程语言中都有的“转义字符”的概念。

^ 匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\\n”或“\\r”之后的位置。

$ 匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\\n”或“\\r”之前的位置。

* 匹配前面的子表达式任意次。例如,zo*能匹配“z”,也能匹配“zo”以及“zoo”。

+ 匹配前面的子表达式一次或多次(大于等于1次)。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。

? 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“do”或“does”中的“do”。?等价于{0,1}。

{n} n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。

{n,} n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。

{n,m} m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。

? 当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配每个“o”即4次匹配,而“o+”将只匹配1次即匹配“oooo”。

.点 匹配除“\\r\\n”之外的任何单个字符。要匹配包括“\\r\\n”在内的任何字符,请使用像“[\\s\\S]”的模式。

(pattern) 匹配pattern并获取这一匹配。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用0…0…9属性。要匹配圆括号字符,请使用“”或“”或“”。

(?:pattern) 非获取匹配,匹配pattern但不获取匹配结果,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分是很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。

(?=pattern) 非获取匹配,正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。

(?!pattern) 非获取匹配,正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。

(?<=pattern) 非获取匹配,反向肯定预查,与正向肯定预查类似,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。

(?<!pattern) 非获取匹配,反向否定预查,与正向否定预查类似,只是方向相反。例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,但不能匹配“2000Windows”中的“Windows”。这个地方不正确,有问题此处用或任意一项都不能超过2位,如“(?<!95|98|NT|20)Windows正确,“(?<!95|980|NT|20)Windows 报错,若是单独使用则无限制,如(?<!2000)Windows 正确匹配。

x|y 匹配x或y。例如,“z|food”能匹配“z”或“food”(此处请谨慎)。“[z|f]ood”则匹配“zood”或“food”。

[xyz] 字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。

[^xyz] 负值字符集合。匹配未包含的任意字符。例如,“[^abc]”可以匹配“plain”中的“plin”。

[a-z] 字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。注意:只有连字符在字符组内部时,并且出现在两个字符之间时,才能表示字符的范围; 如果出字符组的开头,则只能表示连字符本身。

[^a-z] 负值字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。

\\b 匹配一个单词边界,也就是指单词和空格间的位置(即正则表达式的“匹配”有两种概念,一种是匹配字符,一种是匹配位置,这里的\\b就是匹配位置的)。例如,“er\\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。

\\B 匹配非单词边界。“er\\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。

\\cx 匹配由x指明的控制字符。例如,\\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“c”字符。

\\d 匹配一个数字字符。等价于[0-9]。grep 要加上-P,perl正则支持

\\D 匹配一个非数字字符。等价于[^0-9]。grep要加上-Pperl正则支持

\\f 匹配一个换页符。等价于\\x0c和\\cL。

\\n 匹配一个换行符。等价于\\x0a和\\cJ。

\\r 匹配一个回车符。等价于\\x0d和\\cM。

\\s 匹配任何不可见字符,包括空格、制表符、换页符等等。等价于[ \\f\\n\\r\\t\\v]。

\\S 匹配任何可见字符。等价于[^ \\f\\n\\r\\t\\v]。(这里包含空格)

\\t 匹配一个制表符。等价于\\x09和\\cI。

\\v 匹配一个垂直制表符。等价于\\x0b和\\cK。

\\w 匹配包括下划线的任何单词字符。类似但不等价于“[A-Za-z0-9_]”,这里的”单词”字符使用Unicode字符集。

\\W 匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。

\\xn 匹配n,其中n为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,“\\x41”匹配“A”。“\\x041”则等价于“\\x04&1”。正则表达式中可以使用ASCII编码。

\\num 匹配num,其中num是一个正整数。对所获取的匹配的引用。例如,“(.)\\1”匹配两个连续的相同字符。

\\n 标识一个八进制转义值或一个向后引用。如果\\n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n为一个八进制转义值。

\\nm 标识一个八进制转义值或一个向后引用。如果\\nm之前至少有nm个获得子表达式,则nm为向后引用。如果\\nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若n和m均为八进制数字(0-7),则\\nm将匹配八进制转义值nm。

\\nml 如果n为八进制数字(0-7),且m和l均为八进制数字(0-7),则匹配八进制转义值nml。

\\un 匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。例如,\\u00A9匹配版权符号(©)。

\\p{P} 小写 p 是 property 的意思,表示 Unicode 属性,用于 Unicode 正表达式的前缀。中括号内的“P”表示Unicode 字符集七个字符属性之一:标点字符。其他六个属性:L:字母;M:标记符号(一般不会单独出现);Z:分隔符(比如空格、换行等);S:符号(比如数学符号、货币符号等);N:数字(比如阿拉伯数字、罗马数字等);C:其他字符。*注:此语法部分语言不支持,例:javascript。

< > 匹配词(word)的开始(<)和结束(>)。例如正则表达式<the>能够匹配字符串”for the wise”中的”the”,但是不能匹配字符串”otherwise”中的”the”。注意:这个元字符不是所有的软件都支持的。

( ) 将( 和 ) 之间的表达式定义为“组”(group),并且将匹配这个表达式的字符保存到一个临时区域(一个正则表达式中最多可以保存9个),它们可以用 \\1 到\\9 的符号来引用。

| 将两个匹配条件进行逻辑“或”(Or)运算。例如正则表达式(him|her) 匹配”it belongs to him”和”it belongs to her”,但是不能匹配”it belongs to them.”。注意:这个元字符不是所有的软件都支持的。

{i} {i,j} 匹配指定数目的字符,这些字符是在它之前的表达式定义的。例如正则表达式A[0-9]{3} 能够匹配字符”A”后面跟着正好3个数字字符的串,例如A123、A348等,但是不匹配A1234。而正则表达式[0-9]{4,6} 匹配连续的任意4个、5个或者6个数字。

注意:

1)关于[]

a、[+] ->中括号中出现的所有字符都代表的是本身的意思
b、[12-65] ->这个不是12-65而是1/2-6/5三者中的一个

2)关于()

a、分组的作用是改变默认的优先级,例如:/^18|19$/,181、189、119、819、1819...都符合,而不是我们认为的18或19,但是改成/^(18|19)$/就是单纯的18或19了
b、可以在捕获大正则匹配的内容同时,把分组匹配的内容也进行捕获->分组捕获
c、分组引用,例如:/^(\\d)(\\w)\\2\\1$/,这里的\\2是和第二个分组出现一模样的内容,\\1是和第一个分组出现一模一样的内容,例如:"0aa0"就符合了

[代表数量的量词元字符]

* -> 0到多个
+ -> 1到多个
? -> 0到1个
{n} -> 出现n次
{n,} -> 出现n到多次
{n,m} -> 出现n到m次

注意:

1)关于?的几种情况

a、放在非量词元字符后面,代表出现0-1次
b、放在量词元字符后面,代表取消捕获时候的贪婪性,例如:reg=/\\d+/; reg.exec("2015") -> "2015" 但是如果正则这样写 reg=/\\d+?/; reg.exec("2015") -> "2"
c、在分组开头加?:,代表当前的分组只是匹配不进行捕获,例如:/^(?:\\d+)$/
d、在分组开头加?=,正向预查,例如:/^abcdef(?=1|2)$/ 只有"abcdef1"和"abcdef2"才符合
e、在分组开头加?!,负向预查,例如:/^abcdef(?!1|2)$/ 除了"abcdef1"和"abcdef2"不符合,其他的只要是"abcdef(任何的东西)"都符合

[代表本身意思的元字符]

除了以上的,在字面量方式中,我们出现的其他任意字符代表的都是自己本身的意思

var num=12;
var reg=/^\\w"+num+"$/; ->这里"+num+"不是把变量的值拼接,而这里的不管是"还是+都是元字符

->对于需要拼接字符串和变量的方式我们只能使用实例方式创建正则

2、修饰符

i -> ignoreCase 忽略字母的大小写
g -> global 全局匹配 (加上g可以解决正则捕获时候的懒惰性)
m -> multiline 多行匹配

3、项目中常用的正则

1)有效数字的

?

1

var reg=/^[+-]?(\\d|([1-9]\\d+))(\\.\\d+)?$/;

2)邮箱的

?

1

var reg = /^\\w+((-\\w+)|(\\.\\w+))*@[A-Za-z0-9]+((\\.|-)[A-Za-z0-9]+)*\\.[A-Za-z0-9]+$/;

3)电话的

?

1

var reg = /^1\\d{10}$/;

4)年龄在18-65之间的

?

1

var reg = /^((18|19)|([2-5]\\d)|(6[0-5]))$/;

5)中文姓名

?

1

var reg = /^[\\u4e00-\\u9fa5]{2,4}$/;

6)身份证

?

1

2

var reg = /^(\\d{6})(\\d{4})(\\d{2})(\\d{2})(?:\\d{2})(\\d)(?:\\d|X)$/;

//-> 12828(省市县) 1990(年) 12(月) 04(日) 06 1(奇数是男偶数是女) 7(数字或者X)

4、正则的匹配

reg.test([string]) ->true就是匹配成功 false->匹配不成功

5、正则的捕获

1)reg.exec([string])

-> 首先去匹配,匹配成功在捕获,返回的是一个数组; 如果匹配不成功返回的是null;
-> 正则的捕获即懒惰又贪婪
-> 解决懒惰性 在正则的末尾增加全局修饰符g
-> 解决贪婪性 在量词后面加?

2.正则表达式语法支持情况

3.零宽断言

用于查找在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们像\\b,^,$那样用于指定一个位置,这个位置应该满足一定的条件(即断言),因此它们也被称为零宽断言。最好还是拿例子来说明吧:

(?=exp)也叫零宽度正预测先行断言[3] ,它断言自身出现的位置的后面能匹配表达式exp。比如\\b\\w+(?=ing\\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I’m singing while you’re dancing.时,它会匹配sing和danc。

(?<=exp)也叫零宽度正回顾后发断言[3] ,它断言自身出现的位置的前面能匹配表达式exp。比如(?<=\\bre)\\w+\\b会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading。

假如你想要给一个很长的数字中每三位间加一个逗号(当然是从右边加起了),你可以这样查找需要在前面和里面添加逗号的部分:((?<=\\D)\\D{3})+\\b,用它对xxxxxxxxxx进行查找时结果是xxxxxxxxx 下面这个例子同时使用了这两种断言:(?<=\\s)\\d+(?=\\s)匹配以空白符间隔的数字(再次强调,不包括这些空白符)

断言用来声明一个应该为真的事实。正则表达式中只有当断言为真时才会继续进行匹配。

---------------------

作者:BishopTylaor

来源:CSDN

原文:https://blog.csdn.net/github_37443078/article/details/79894017

版权声明:本文为博主原创文章,转载请附上博文链接!

由于网站搬家,部分链接失效,如无法下载,请联系站长!谢谢支持!
1. 带 [亲测] 说明源码已经被站长亲测过!
2. 下载后的源码请在24小时内删除,仅供学习用途!
3. 分享目的仅供大家学习和交流,请不要用于商业用途!
4. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
5. 本站所有资源来源于站长上传和网络,如有侵权请邮件联系站长!
6. 没带 [亲测] 代表站长时间紧促,站长会保持每天更新 [亲测] 源码 !
7. 盗版ripro用户购买ripro美化无担保,若设置不成功/不生效我们不支持退款!
8. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
9. 如果你也有好源码或者教程,可以到审核区发布,分享有金币奖励和额外收入!
10.如果您购买了某个产品,而我们还没来得及更新,请联系站长或留言催更,谢谢理解 !
GG资源网 » 关于正则表达式 大于等于100 或者小于100的正则表达式

发表回复

CAPTCHAis initialing...