`
wyzxzws
  • 浏览: 392743 次
  • 性别: Icon_minigender_1
  • 来自: dazhou
社区版块
存档分类
最新评论

Perl正则表达式(Regular Expression, regex)

阅读更多
如果要问我Perl语言的优点,我会说有三个半。前三个是正则表达式、哈希、引用,那半个是Map, 因为还不大会用,不太说得出它的秒处,所以算半个。其实哈希、引用、Map都算是数据结构的范畴;正则表达式和它们差异比较大。人类的思维里有很多正则表达式的痕迹,甚至用这种方式训练下一代。比如一位完全文科思维的幼儿园教师,也会教育她的学生从一桶积木里找出一个红的方块来。"红而且方的积木",这就是一个自然语言的正则表达式。正则表达式也经常被称为模式,用来描述或者匹配一系列符合某个句法规则的字符串。

一定有人还记得在dos和Unix下面的这些命令:

    $ls -l img1?.jpg
    C:>dir *.exe

这里的星号通配符和问号通配符就是正则表达式符号,确切地说是Dos shell和Unix shell使用的正则表达式符号。Perl的正则表达式规则与这两些shell的都有所不同,但Perl的正则表达式影响最大,几乎成了业界标准,以至于近年来新建的一些计算机语言都要申明自己实现了Pcre(Perl兼容的正则表达式),要不然都不好意思出来混江湖(微软除外)。
<!-- @page { size: 21cm 29.7cm; margin: 2cm } P { margin-bottom: 0.21cm } --> Perl正则表达式 (Regular Expression, regex)

Perl正则表达式的使用很简单(其实实现起来很难),跟我来:

1. Perl正则表达式相关的操作符

先不说正则表达式本身,下面我们的正则表达式就用"apple". 先定义一个字符串

    my $szProductType = "apple cider";

现在要检验它里面有没有字符串"apple"。

    if( $szProductType =~ /apple/){

    print $szProductType."\n";

    }

上面的=~要看做一个符号,是Perl的正则表达式匹配操作符。这个符号匹配成功返回1,否则返回0。后面的两个/之间包括的就是正则表达式,这是就是apple。正则表达式也可以不用/符号而改用其它符号包括,鉴于海马一向厌恶这种标新立异做无用功的行为,就不说怎么操作了,偏执到不喜欢/符号的人请自己去查Perl手册吧。如果要求匹配一个字符串里面没有"apple"怎么办?当然可以这样(花括号里该写什么自己写吧,我省略啦)

    unless ($szProductType =~ /apple/){ }

还可以这样

    if( ! ($szProductType =~ /apple/)){}

但是,为了表示你很懂Perl, 你应该这样,这也是我最喜欢的方式(画外音:这和前面那个被批判的标新立异有啥区别,嗯?),使用不匹配操作符号!~。

    if( $szProductType !~ /apple/)){}

最后,为了避免被人看穿自己很不懂Perl,看到下面的表达式的时候千万不要露怯

    if( $szProductType !~ m/apple/)){}

这个m是干什么的?答案是,这个地方有m没m一样的,都是表示匹配(match)。请直接无视之。对于匹配操作符也是一样的情况。


2. Perl正则表达式语法

所谓正则表达式,就是一串特别设计过的字符串,可以按照你的意图用匹配操作寻找你要求的目标。我这里不是Perl手册,也不是教科书,所以我从例子开始,具体的完整说明还请查手册。


2.1 转义符号\

前面说过缺省情况下正则表达式要用/包起来,那么现在要寻找一个字符串里面有没有/怎么办?不是有歧义了么那个表达式。换你设计Perl语言该咋办?玩过C语言的人看到这里一定在嘿嘿笑,因为在C里面简单,要写/必须写成\/,要写\必须写成\\。说Perl在语法上是C的表弟是很不错的,Perl规定的转义符号也是\. 常用的特殊符号有回车\n, 跳格\t, 斜杠\\和\/,引号\'和\",方括号\[和\],圆括号\(和\),美元号\$,上尖号\^,星号\*,点号\.,问号\?,加号\+。我都是随手写的,建议拿不定主意的话,非52个字母的符号都去查查手册吧。举例:查一个字符串里有没有美元号

    my $szValue = '$6580.90';
    $szValue =~ /\$/;


2.2 或操作

Perl的正则表达式缺省是区别大小写的。什么,前面早该告诉你?真可怜,又一个从Windows世界来的小孩,就和我想当然以为在美国商店应该在复活节大做生意创造GDP一样,可是人家不开门。为了串即匹配"Apple"又匹配"apple",你可以这样:

    $szProductType =~ /[Aa]pple/;

在方括号里的字母是"或"的关系,击中其中一个就可以了。在一个正则表达式中可以用任意多个方括号,但是不要嵌套。常常能见到的一种表达式

    [0-9]

表示0到9这十个字母,也可以用\d来代替。\D则表示非数字字符。

    [a-zA-Z]

表示52个字母。

顺便在这里把反义也讲了吧,[^0-9]代表非数字的其它字符,[^a]代表非a的其它字符。^在这里是反义的意思,但是请注意^还能做头锚用,后面会讲到。


2.3 尾缀

有人摇头不喜欢上面的解决方案――我要求真正匹配一个不区分大小写的"Apple"应该怎么办?请这样

    $szProductType =~ /apple/i;

放在第二个/符号后面的尾缀i取消了一切大小写检查。


另外再说两个有用的尾缀吧,第一个是g(全局匹配),如果有字符串

    my $string = "Apple juice, apple Cider, apple jeans, apple pie, apple plate, apPLe bag,…";

而用表达式$string =~ /apple/i;只会遇到第一个apple就结束。现在我们可以用尾缀g配合while循环

    while( $string =~ /(apple.*?),/ig){
    print "$1\n";
    }

就可以找出所有带apple的词汇。注意尾缀是可以叠加使用的。上面正则表达式中的圆括号、点号和问号和$1,下面马上会讲到。


另一个有用的的尾缀是s。s会强迫点号(.)匹配换行符号(\n),这对于多行匹配是必须的。不要小看这个技巧,我花了几个小时才找到的哦。


2.4 捕获匹配的字符串

    my $szValue = '$1999.99';

    if( $szValue =~ /\$([0-9]+)\.([0-9]+)/){

    print "$1 dollors $2 cents \n";

    }

上面表达式里的加号表示匹配一到多个前面的符号,在这里符号是数字。用圆括号括住的内容,将会依次(从左到右)出现在$1, $2, $3……里面。另外,顺便说,整个正则表达式匹配的结果是放在$&里面,上面这个表达式演算下来$&的值还是"$1999.99"。

另外,还有\1, \2形式的反向引用,使得表达式里面可以用捕获的字符串。举例:表达式 "(\w)\1{4,}" 在匹配 "aa bbbb abcdefg ccccc 111121111 999999999" 时,匹配结果是:成功;匹配到的内容是 "ccccc"。再次匹配下一个时,将得到 999999999(要用while和/g来配合)。


2.5 任意符号.,和次数符号*以及+

Perl正则表达式里点号是通配任意字母的,例如

    $string =~ /w.*/i;

就匹配$string里从第一个w字母开始一直到字符串结束。*表示匹配任意字母0到任意多次。*号也常被换成+号,表示匹配1到任意多次。如果即没有*也没有+,那么就是匹配1次。如果要自己定义匹配的次数或者次数上下限怎么办?用{}符号:

    $string =~ /\d{5,15}/;

上面的式子匹配5到15位数字

    $string =~ /\d{20}/;

上面的式子匹配20位数字。


附带说两个常用的符号,\S和\s。前者是"非空白",后者是"空白",具体来说包括回车、空格、跳格、响铃。


2.6贪婪的+和*,止贪剂?

Perl的正则表达式是贪婪的(确切地说,次数符号+和*是贪婪的),可以帮助你做一些事情。

    my $string = '$290098';

    $string =~ /\$(\d+)/;

由于+号的贪婪性,$1会得到值"290098",而不是遇到第一个数字2就完成匹配。


但有的时候你会不希望他贪婪,希望见好就收。还是我前面用过的一个例子

    my $string = "Apple juice, apple Cider, apple jeans, apple pie, apple plate, apPLe bag,…";

如果用

    $string =~ /(apple.*),/i;

由于*的贪婪性,它会一直匹配到最后一个逗号才停下来,这不是我们想要的结果。解决办法是用止贪符号?紧跟在*或者+后面。

    $string =~ /(apple.*?),/i;

问号会约束*遇到第一个逗号就停下来。


2.6 头锚^和尾锚$

有时候你希望从一个字符串的开始或者结尾匹配

    my $string = 'A quick brown fox jumps over a lazy snake';

$string =~ /^A/; # 匹配第一个字母是否为A

$string =~ /snake$/; # 匹配最后几个字母是否为snake

还有一个\b,匹配的是单词边界,意思是空白或者开头或者结尾。

3. 其它相关函数及注意事项

3.1 替换功能和quotemeta

有时候你不仅希望找到你想要那些字符串,还想替换掉它们。还记得前面说的匹配符后面的m符号么?现在是使用另一个,s符号(替换,subplace)的时候了。

    $string =~ s/apple/apple/i;

上面表达式将$string里所有不用形式的apple统一成全小写的apple. 这里面可以用变量:

    $string =~ s/$string1/$string2/i;

$string里所有匹配$string1的地方都会被替换成$string2。但是,要注意,除非你能确保$string1里面不含任何特殊符号(+-*^$.()[]等)或者你需要的就是那些符号,最好在调用上面式子之前处理一下$string1

    $string1 = quotemeta($string1);

quotemeta()的作用是给字符串里的特殊符号加上合适的转义符号。注意,不需要给$string2做这个处理。

3.2 不要在while里改变字符串

还记得2.3里面的while循环么?警告:不要在while循环里改变$string的值,否则可能会陷入无限循环。如果你真得这样做,把$string复制一次,一个镜像用来循环,一个用来做替换。

3.3 study及提高性能

有很多人想了很多种办法来提高Perl正则表达式的性能,我一概记不住。如果你要处理的字符串很庞大。。。记得在对它使用正则表达式之前用官方方法对它study一下:

    study($string);

据说这样可以提高一点性能。其实如果要性能,还是建议用Java,Java也有正则表达式;或者对性能有更高要求的话,建议用 C/C++。标准的C和 C++都不支持正则表达式,但有一些函数库可以辅助C/C++程序员完成这一功能,其中最著名的当数Philip Hazel的Perl-Compatible Regular Expression库,许多Linux发行版本都带有这个函数库。使用方法看这里

http://www.chinaunix.net/jh/23/303346.html

在Windows上面,VC.NET(VC7)框架里是有正则表达式了。警告:微软的老大们并没有实现Perl兼容。例如,在 Perl 中,{,1}是{0,1}的简写,但.NET并不支持。具体看这里
分享到:
评论

相关推荐

    正则表达式测试工具RegexTester 中文版

    正则表达式(Regular Expression,简称regex)是用于匹配字符串的一种模式,广泛应用于文本处理、数据验证、搜索和替换等场景。RegexTester是一款强大的正则表达式测试工具,专为帮助用户验证和调试正则表达式设计。...

    正则表达式 Regular Expression 正则表达式资料大全压缩包

    正则表达式(Regular Expression,简称regex)是用于在文本中匹配特定模式的强大工具,它在编程、数据处理和文本分析等领域中广泛应用。这个“正则表达式资料大全压缩包”很可能包含了各种教程、示例、参考手册以及...

    正则表达式测试工具RegexTester

    正则表达式(Regular Expression,简称regex)是一种模式匹配语言,用于在文本中查找、替换或提取特定的字符串模式。它们广泛应用于数据验证、搜索、文本处理等场景。RegexTester工具使得这个过程变得更加简单和直观...

    精通正则表达式(第三版)简体中文版

    正则表达式(Regular Expression)是一种强大的文本处理工具,能够帮助用户查找、替换以及操作特定的字符串或字符组合。它在多种编程语言和操作系统中都有广泛的应用。本书《精通正则表达式(第三版)简体中文版》...

    正则表达式(Regular Expression,简称 regex 或 regexp)是一种强大的文本匹配工具,在编程和文本处理

    正则表达式:正则表达式(Regular Expression,简称 regex 或 regexp)是一种强大的文本匹配工具,在编程和文本处理中非常有用。它可以用于搜索、编辑、或操纵文本。几乎所有现代编程语言都支持正则表达式的使用,...

    正则表达式桌面测试 RegexPal+本地中文版

    正则表达式(Regular Expression,简称regex)是一种用于匹配字符串的强大工具,广泛应用于文本处理、数据提取、验证输入等IT领域。RegexPal是一款简洁而实用的在线正则表达式测试工具,现在它提供了本地中文版,使...

    csharp正则表达式参考手册

    (英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。 许多程序设计语言都支持利用正则表达式进行字符串操作。...

    C/C++ Regex/Regular Expression(C/C++正则表达式库实现)

    在C/C++编程环境中,正则表达式(Regex或Regular Expression)是一种强大的文本处理工具,用于模式匹配、字符串查找、替换等操作。由于C++标准库并没有内置完整的正则表达式支持,直到C++11标准引入了`&lt;regex&gt;`库,...

    regex-正则表达式教程.pdf

    "regex"一词来源于"Regular Expression",用来表示一个特定的字符串或字符串集合。例如,正则表达式"a"会匹配字符串中首次出现的字母"a",而"cat"会匹配包含连续字母"c"、"a"和"t"的字符串。 正则表达式的应用广泛...

    深入浅出之正则表达式(一)

    正则表达式(Regular Expression,简称Regex)是一种模式匹配语言,用于描述一组文本字符串的特征。例如,"cat" 这个正则表达式可以匹配任何包含连续的 "c"、"a" 和 "t" 的字符串。正则表达式不仅限于单个字符,还...

    正则表达式之道

    (英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。 许多程序设计语言都支持利用正则表达式进行字符串操作。...

    《精通正则表达式第三版 E文》

    正则表达式(Regular Expression,简称regex)是一种模式匹配语言,能够高效地进行文本查找、替换和分析。它由一系列特殊字符和普通字符组成,用于定义字符串的模式。例如,`\d{3}-\d{4}` 可以用来匹配电话号码格式...

    45 - Nginx中的正则表达式.mp4

    (英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。 许多程序设计语言都支持利用正则表达式进行字符串操作。...

    电话号码及日期时间提取(正则表达式 C)

    在IT领域,正则表达式(Regular Expression)是一种强大的文本处理工具,用于匹配、查找、替换等操作。在本项目中,“电话号码及日期时间提取(正则表达式 C)”是一个使用C语言编写的程序,它能够从文本中有效地识别...

    6款正则表达式工具

    正则表达式(Regular Expression,简称Regex)是用于匹配字符串的一种模式,广泛应用于文本处理、数据提取、验证输入等场景。在IT行业中,熟练掌握正则表达式是提高工作效率的关键技能之一。本篇文章将介绍一款名为...

    正则表达式30分钟入门教程.rar

    (英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。 许多程序设计语言都支持利用正则表达式进行字符串操作。...

Global site tag (gtag.js) - Google Analytics