分享
 
 
 

正则表达式及其应用简介

王朝other·作者佚名  2006-03-10
窄屏简体版  字體: |||超大  

浪潮软件技术研究中心 申科建

1 介绍

正则表达式(Regular Expressions)描述了一种字符串匹配的模式,可以用来检查一个字符串是否含有某种子串、将匹配的子串做替换或者从某个字符串中取出符合某个条件的子串等。这样的表达式“^[+|-]?\d*\.\d+$”,如果以前从没接触过,乍看的确像古老的咒语,只有巫师能懂。但这正是表达式的强大之所在,正则表达式把复杂的问题简单化,简单到只有几个字符。如果不理解规则,就会把简单的几个字符复杂化,复杂到不可理解,但如果理解规则,那么就会发现,表达式就是表达式,它的确就是几个符号,表达一个明确的意思。

2 正则表达式的组成

正则表达式由特殊字符以及普通字符组成,特殊字符是正则表达式规则定义的有特殊含义的字符,普通字符是除特殊字符外的所有打印和非打印字符。

2.1 打印字符

所有大小写字母,所有数字,所有标点符号,以及一些特殊符号。

2.2 非打印字符

字符

含义

\cx

匹配由x指明的控制字符。例如, \cM 匹配一个 Control-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 和 \cI。

\v

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

2.3 特殊字符

特殊字符是有特殊含义的字符,如果需要使用它的原义,必须在字符前使用“\”进行转义(此处不再列举)。

3 操作符优先级

相同优先级的从左到右进行运算,不同优先级的运算先高后低。各种操作符的优先级从高到低如下:

操作符

描述

转义符

(), (?:), (?=), []

圆括号和方括号

*, +, ?, {n}, {n,}, {n,m}

限定符

^, $, \anymetacharacter

位置和顺序

|

“或”操作

4.正则表达式的简单示例

4.1 基本模式匹配

表达式“friend”匹配一个字符串中任何位置的“friend”。

4.2 定位符匹配

表达式“^friend$”只匹配“friend”字符串。其中^表示匹配字符串开始位置,$表示匹配字符串结束位置。

4.3 字符簇匹配

表达式“^[abcd]”匹配一个字符串中开始位置的a或b或c或d字符,只匹配一个字符。

表达式“^[^ab]”匹配一个字符串中开始位置的非a或b的字符,其中^在“[]”中表示“非”,而不是开始位置。

表达式“^[A-Z]”匹配一个字符串中开始位置的大写字符,其中“-”表示范围。

4.4重复次数

表达式“ab{2}”匹配一个字符串中的“abb”,其中“{2}”表示前面的子表达式重复2次。

表达式“ab{0,}”匹配一个字符串中的a加任意多个b(包括0个),其中“{0,}”表示前面的子表达式重复0或多次,“*”也可以表示0或多次,所以也可以写成“ab*”。

表达式“ab{1,}”匹配一个字符串中的a加1个或任意多个b,其中“{1,}”表示前面的子表达式重复1次或多次,“+”也可以表示重复1次或多次,所以也可以写成“ab+”。

表达式“ab{0,1}”匹配一个字符串中的“a”或“ab”,其中“{0,1}”表示前面的子表达式重复0次或1次,“?”也可以表示0次或1次,所以也可以写成“ab?”。

4.5 正则表达式的贪婪性

正则表达式默认总是尽可能多的匹配字符串,这种特性叫做正则表达式的贪婪性。例如表达式“a+”将匹配字符串“aaaaaaaa”中的所有a。

如果想改变这种特性,可以使用“?”,使表达式尽可能少的匹配字符串。例如表达式“^a+?”将匹配字符串“aaaaaa”中的第一个a。

4.6 一个实用例子

前面提到的表达式“^[+|-]?\d*\.\d+$”表示一个浮点数。^表示开始,[+|-]表示是+或-,?表示+-号有或没有,\d*表示0或多位数字,\.表示小数点,\d+表示1或多位数字,$表示结束。

5 正则表达式应用示例

下面的例子,只是简单介绍正则表达式在JavaScript、Java、C中的应用。虽然正则表达式有标准,但是在具体实现时,并非完全相同,还有一些差异,如果想更全面、深入的了解,请参考相关资料。

5.1 正则表达式在JavaScript中的应用

JavaScript中有一个RegExp类用来处理正则表达式,下面是一个例子,判断一个输入是否是浮点数:

<Script language=”JavaScript”>

<!--

function checkFloat(str) {

var re = /^[+|-]?\d*\.\d+$/;

return re.test(str);

}

//-->

</Script>

JavaScript中的String类也有一些函数用到正则表达式,下面是一个例子,将日期从yyyy-mm-dd格式转换成yyyy年mm月dd日格式:

<Script language=”JavaScript”>

<!--

function changeFormat(str) {

return str.replace(/(\d{4})-(\d{2})-(\d{2})/, "$1年$2月$3日");

}

//-->

</Script>

5.2 正则表达式在Java中的应用

Java中的java.util.regex包提供对正则表达式的支持,下面是一个例子,判断一个输入是否是浮点数:

public static boolean checkFloat(String str) {

return Pattern.matches("^[+|-]?\\d*\\.\\d+$", str);

}

注意:在java语言中,String中的\使用\表示

Java中的String类也有一些函数使用正则表达式,下面是一个例子,将日期从yyyy-mm-dd格式转换成yyyy年mm月dd日格式:

public static String changeFormat(String str) {

return str.replaceAll("(\\d{4})-(\\d{2})-(\\d{2})", "$1年$2月$3日");

}

5.3 正则表达式在C语言中的应用

需要包含两个头文件:sys/types.h、regex.h,有四个函数:regcomp编译表达式函数,regexec表达式处理 函数,regerror错误处理函数,regfree释放资源。

下面一个例子,判断一个输入是否是浮点数:

int checkFloat(char *str) {

int n;

regex_t re;

regmatch_t pm[10];

char buf[256], pattern[256];

strcpy(pattern, "^[+|-]?[0-9]*\\.[0-9]+$");

n = regcomp(&re, pattern, REG_EXTENDED);

if (n != 0) {

regerror(n, &re, buf, sizeof(buf));

fprintf(stderr, “err:[%d]%s”, n, buf);

return n;

}

n = regexec(&re, str, sizeof(pm)/sizeof(regmatch_t), pm, 0);

if (n != 0) {

if (n != REG_NOMATCH) {

regerror(n, &re, buf, sizeof(buf));

fprintf(stderr, “err:[%d]%s”, n, buf);

}

}

regfree(&re);

return n;

}

下面是一个例子,将日期从yyyy-mm-dd格式转换成yyyy年mm月dd日格式:

int changeFormat(char *str) {

int n, i;

regex_t re;

regmatch_t pm[10];

char buf[256], pattern[256];

strcpy(pattern, "([0-9]{4})-([0-9]{2})-([0-9]{2})");

n = regcomp(&re, pattern, REG_EXTENDED);

if (n != 0) {

regerror(n, &re, buf, sizeof(buf));

fprintf(stderr, "err:[%d]%s", n, buf);

return n;

}

n = regexec(&re, str, sizeof(pm)/sizeof(regmatch_t), pm, 0);

if (n != 0) {

if (n != REG_NOMATCH) {

regerror(n, &re, buf, sizeof(buf));

fprintf(stderr, "err:[%d]%s", n, buf);

}

} else {

memset(buf, 0x00, sizeof(buf));

strncpy(buf, str + pm[1].rm_so, pm[1].rm_eo - pm[1].rm_so);

strcat(buf, "年");

strncat(buf, str + pm[2].rm_so, pm[2].rm_eo - pm[2].rm_so);

strcat(buf, "月");

strncat(buf, str + pm[3].rm_so, pm[3].rm_eo - pm[3].rm_so);

strcat(buf, "日");

strcpy(str, buf);

}

regfree(&re);

return n;

}

6 结束语

正则表达式应用非常广泛,在字符串处理时,往往有意想不到的效果,但写出高技巧的表达式,往往需要一定的功底,。

表达式其实不难,难的是记住它的规则,我认为最好的方法是多用,不需要死记规则,碰到不理解的规则查找资料,用多了就记住了。当然了,如果你超强能记住规则最好。

另外,虽然有标准,但不同的地方还是有细微差别的,在使用时也需要注意。

7 参考资料

正则表达式标准:http://www.opengroup.org/onlinepubs/007908799/xbd/re.html

网友笑容编写的《正则表达式(regular expression)》http://dev.csdn.net/develop/article/41/41299.shtm

Jeffrey E.F.Friedl编写的《Mastering Regular Expressions》,这本书是正则表达式的极好资料,不过是E文的,780页,太多了,我没参考。

另外还有从网上找的其他资料,不再一一列举。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有