简析正则表达式

前段时间我利用业余时间开发了一套基于标签的CMS系统,在其中为了处理基于标签的数据提取与数据填充大量的使用了正则表达式,在这里将我将正则表达式的语法和用法进行简单的描述,然后下篇中将介绍在c#中利用正则表达式的方法与代码实例。

什么是正则表达式
基本说来,正则表达式是一种用来描述一定数量文本的模式。Regex代表Regular Express。我们使用一种自定义的模式来匹配一定数量的文本,并从中提取所需数据。如同window的通配符,如:*.txt查找所有txt文件。*就被解释成任意字符。

一个简单的正则表达式

作为惯例,我们都是从hello world开始的。那么这里同样这样开始。为了匹配hello world这11个字符,正则表达式为:^hello\sworld$。其中^代表开头的锚点、$代表结束的锚点、\s代表匹配一个空格。一个重要的注意事项,正则表达式是占位的,也就是说,正则表达式中的一个字符一定要对应实际文本中的一个字符。如上面的正则表达式就不能匹配” hello world”,因为” hello….”前面多了一个空格。

另一个正则表达式
如果我们需要匹配一个ipv4的ip地址;总所周知,ip地址分为4段,每段以’.’分割。每段大小在0-255之间。其中前三段都以’.’结尾,最后一段没有。经过分析得到如下结论。

1) 前三段的匹配模式是相同的,最后一段的匹配模式与前三段只是不以’.’结尾

2) Ipv4的ip地址每段范围在0-255之间。可以是0-9,可以是10-99,也可以是100-255。其中需要主要的是100-199范围和200-255范围,如果首位以1开头,则后两位可以是任意数字,如果首位以2开头,第二位只能是0-5,而且,当第二位是0-4的时候第三位可以是任意数字,当第二位是5的时候第三位只能是0-5

下面我们写出符合上面第二点的匹配模式

① 当首位是2,且第二位是0-4的时候:2[0-4]\d,

② 当首位是2,且第二位是5的时候:25[0-5]

③ 当首位是0或则1的时候,第二三位可以是任意数字:[01]\d\d

④ 当首位不是0-2的时候,这时该地址就不能是100-255的范围,只能是0-9或者10-99的范围,当在0-9范围的时候,一位任意数字就可以:\d,当在10-99的时候,两位数字就可以:\d{2};

⑤ 然后观察第③和第④点可以发现,当首位是0-1而且出现三位的时候应用第③点,当首位不是0-1且不是三位时应有第④点。变可以融合第③④点为:[01]?\d\d?

现在每段0-255范围的匹配模式已经书写完成了,然后考虑前三段以’.’结尾的问题,最终获得匹配模式: ^(2[0-4]\d|25[0-5]|[01]?\d\d?\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$

元字符
通过以上的两个实例,相信大家已经对正则表达式有了一个初步的理解,现在这里列出正则表达式的元字符,元字符的定义和语言的关键字含义类似,都是一些在系统中有特殊含义的字符。

1) ‘.’ :匹配任意字符

2) \w :匹配字母或数字或下划线或汉字

3) \s :匹配空白字符

4) \d :匹配任意数字

5) \b :匹配开头或则结尾

6) ^ :匹配字符串的开头

7) $ :匹配字符串的结尾

重复与贪婪重复和惰性重复
重复的含义是指重复匹配满足某一匹配模式的文本。如例中(匹配ip)的’?’号就是一个重复的例子,它的含义是某一匹配模式,至多出现一次。以下列出一些重复的标示:

1) * :星号,重复任意多次,如:\w*,代表任意字母,数字,下划线,汉字出现任意多次

2) + :加号:至少出现一次,如:\d+,代表任意数字至少出现一次

3) ? :问好:至多出现一次(出现一次或则不出现),如:\s?,代表空白字符出现0或则1次

4) {n}:n代表任意数字,如:.{5},代表任意字符出现5次

5) {n,}:n代表任意数字,如:\d{5,},代表任意数字出现5到多次

6) {n,m}:n,m代表任意数字,如:\d{5,10},代表任意数字出现5到10次

贪婪与惰性匹配

首先看一个正则表达式例子:“<.*>”

这个正则表达式将匹配以’<’开头,’>’结尾中间任意次任意字符,如:<br/>,<div/>,</script>等。当如果用该正则表达式去匹配<div>hello world</div>的话被匹配出的文本就是<div>hello world</div>,因为默认情况下正则表达式是贪婪匹配。正则表达式引擎或默认情况下将默认搜索最后一个匹配锚点。所以本例中的最后匹配锚点是</div>的>而不是<div>的>。这便是贪婪匹配。

既然明白有贪婪匹配,就必然需知惰性匹配

以上为上面这个正则表达式例子稍作改动:<.*?>,我们在*后面加上一个问号便告诉引擎按照惰性匹配的方式进行搜索,使用这个正则表达式匹配<div>hello world</div>得到的结果会有两个,一个是<div>另一个是</div>。因为我们没有限定开头和结尾。

字符集,分歧,反义

字符集:[A-Za-z0-9],匹配一个字符,这个字符是A-Za-z0-9中的任意一个

分歧:(a|b)*,a或则b出现任意多次

反义:[^ab]+,非a和b出现至少一次

分组
正则表达式的分组以()小括号进行标示,如:(\w*)。标示将\w*划分为一个匹配单元,及分组。<(\w+?)[A-Za-z0-9"=\s]*>.*?</\1>这个正则表达式能够匹配如:<div class=”box”>hello world</div>段,值得注意的是我们将\w+进行了分组,然后再后面使用\1引用本分组。默认情况下,引擎将至左向右将第一个分组命名为第1组,第二个分组命名为第2组......我们也能显示的给分组命名,本实例中正则表达式也能写成:<(?<g1>\w+?)[A-Za-z0-9"=\s]*>.*?</\k<g1>>我们将\w+的分组命名为g1,以后通过\k<name>引用。

转载自 https://www.cnblogs.com/GuoPeng/archive/2011/05/05/2037588.html

时间: 2024-07-30 15:07:56

简析正则表达式的相关文章

HTML5前端入门教程:简析正则表达式

很多人对正则表达式的印象都是用来做表单验证的,这其实是不大准确的.正则表达式目前在很多软件中都得到了广泛的应用,包括Linux,Unix等操作系统,VB,Java,PHP等开发环境中,以及很多应用软件都能应用到正则表达式. 一.正则的历史 首先先来扫清一个误区,老是有人认为正则表达式是JS自己发明的,这当然是不正确的.1956年,一位名叫Stephen Kleene的数学家在McCulloch和pitts早期工作的基础上,发表了一篇标题为<神经网的表示法>的论文,第一次引入了正则表达式的概念.

借助LANMT构架,简析ngnix的使用

LNMP流程图 nginx PHP Mysql Nginx Fastcgi_pass <-FastCGI-> fastcgi-(php-fpm)<->wrapper Php 解析器 (Php.ini) <->mysql fastcgi-(php-fpm)<->wrapper fastcgi-(php-fpm)<->wrapper fastcgi-(php-fpm)<->wrapper fastcgi-(php-fpm)<->

sed简析

写一个shell命令,统计apache日志文件(access_log)中某一天中每个URL的访问次数,并按照次数由小到大的顺序排序输出:# cat /application/nginx/logs/20170202_access_www.log |awk '{print $7}'|sort| uniq -c |sort -n awk  '{print $7}' 匹配到 url 记录即日志文件格式的($http_referer)字段sort  是排序 ,并且标准输出到屏幕uniq -c  统计重复的

JDK源码简析--java.util包中的工具类库

题记 JDK,Java Development Kit. 我们必须先认识到,JDK只是,仅仅是一套Java基础类库而已,是Sun公司开发的基础类库,仅此而已,JDK本身和我们自行书写总结的类库,从技术含量来说,还是在一个层级上,它们都是需要被编译成字节码,在JRE中运行的,JDK编译后的结果就是jre/lib下得rt.jar,我们学习使用它的目的是加深对Java的理解,提高我们的Java编码水平. 本系列所有文章基于的JDK版本都是1.7.16. 本节内容 在本节中,简析java.util包所包

web应用构架LAMT及tomcat负载简析

Httpd    (mod_jk.so) workers.properties文件 uriworkermap.properties文件 <--AJP1.3--> Tomcat  --> jdk 大致流程:apache服务器通过mod_jk.so 模块处理jsp文件的动态请求.通过tomcat worker等待执行servlet/JSP的tomcat实例.使用 AJP1.3协议与tomcat通信.tomcat有借助jdk解析. 负载就是 多台tomcat.共同解析apache发送的jsp请

CentOS的网络配置简析

我们在进行对CentOS的网络配置时,一般会从IP地址(IPADDR).子网掩码(NETMASK).网关(Gateway).主机名(HOSTNAME).DNS服务器等方面入手.而在CentOS中,又有着不同的命令或配置文件可以完成这些配置操作,接下来,我们将从ifcfg系命令,iproute2系命令以及配置文件3个方面来简析网络配置的方法. 一.ifcfg系命令 ifcfg系命令包括ifconfig,route,netstat和hostname. 1.ifconfig命令 用来配置一个网络接口.

JDK源码简析--java.lang包中的基础类库

题记 JDK,Java Development Kit. 我们必须先认识到,JDK只是,仅仅是一套Java基础类库而已,是Sun公司开发的基础类库,仅此而已,JDK本身和我们自行书写总结的类库,从技术含量来说,还是在一个层级上,它们都是需要被编译成字节码,在JRE中运行的,JDK编译后的结果就是jre/lib下得rt.jar,我们学习使用它的目的是加深对Java的理解,提高我们的Java编码水平. 本系列所有文章基于的JDK版本都是1.7.16. 本节内容 在本节中,简析java.lang包所包

经验模态分解法简析 (转)

http://blog.sina.com.cn/s/blog_55954cfb0102e9y2.html 美国工程院士黄锷博士于1998年提出的一种信号分析方法:重点是黄博士的具有创新性的经验模态分解(Empirical Mode Decomposition)即EMD法,它是一种自适应的数据处理或挖掘方法,非常适合非线性,非平稳时间序列的处理,本质上是对数据序列或信号的平稳化处理. 1:关于时间序列平稳性的一般理解: 所谓时间序列的平稳性,一般指宽平稳,即时间序列的均值和方差为与时间无关的常数,

Java Annotation 及几个常用开源项目注解原理简析

PDF 版: Java Annotation.pdf, PPT 版:Java Annotation.pptx, Keynote 版:Java Annotation.key 一.Annotation 示例 Override Annotation Java 1 2 3 @Override public void onCreate(Bundle savedInstanceState); Retrofit Annotation Java 1 2 3 @GET("/users/{username}&quo