⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 perlreg_8rule.html

📁 这是一个介绍 linux 编程知识的文章。
💻 HTML
📖 第 1 页 / 共 5 页
字号:
<P ALIGN="JUSTIFY"> 6 ' catch as catch can' =~ m" ^(.*)can$; # $1 = ' catch as 
  catch'</P>
<P ALIGN="JUSTIFY"> 7 ' can as catch catch' =~ m"^can(.*)$ # $1 = ' as catch catch'</P>
<P ALIGN="JUSTIFY"> 8 ' word_with_underlines word2' =~ m" \b(\w+)\b; # $1 = word_with_underlines</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"> 每个例子中,我们使用了一个不同的通配符,在该程序中,用*表示在“一行中匹配零个或者多个通配符”。用+表示“在一行中匹配一个或者多个通配符”。这些例子中有些本身就是有用的:例5展示了使用\s*来加强表达式对付散乱空格的方法;例8示例了匹配一个单词的一般化方法;例4示范了使用关键字匹配哈希结构的一般化方法。</P>
<P ALIGN="JUSTIFY"> 然而,特殊地.例1不是匹配Perl数字的通用方法。但是如果给出Perl支持的所有格式,那么这会是一个十分困难的问题。我们将在后面把它作为一个问题考虑。在该表中还有一个地方需要注意:一些适配符被标记为“零宽度断言”,我们在下面讲述仑们。</P>
<P ALIGN="JUSTIFY"> (2)零宽度断言和正宽度断言</P>
<P ALIGN="JUSTIFY"> 在表 9-2 中的字符就是读者可能称作的正宽度断言:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="CENTER">表 9-2 正声明</P>
<P ALIGN="JUSTIFY"> \D 非数字</P>
<P ALIGN="JUSTIFY"> \d 数字</P>
<P ALIGN="JUSTIFY"> \w 单词</P>
<P ALIGN="JUSTIFY"> \W 非单词</P>
<P ALIGN="JUSTIFY"> \s 空格</P>
<P ALIGN="JUSTIFY"> \S 非空格</P>
<P ALIGN="JUSTIFY"> ' .' 换行符以外的任意字符。</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"> 这些断言在字符串中实际上匹配一个字符。正宽度意味着匹配一个字符,同时正则表达式引擎在匹配过程中“吃掉”它们。在表 9-3 
  中列出的负宽度断言。</P>
<P ALIGN="JUSTIFY"> 这些断言不是匹配一个字符,它们匹配的是一种条件。换句话讲,^cat匹配以cat开头的字符串,但并不匹配任一给定字符。请看下面的表达式:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="JUSTIFY"> $ziggurautString = ' this matches the word zigguraut';</P>
<P ALIGN="JUSTIFY"> $ziggurautString =~ m" \bzigguraut\b";</P>
<P ALIGN="JUSTIFY"> $ziggurautString =~ m" \Wzigguraut\W";</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="CENTER"> <IMG SRC="images/Image7.jpg" WIDTH=504 HEIGHT=98></P>
<P ALIGN="JUSTIFY"> 第一个例子匹配成功,因为它是在两个非单词字符(单词边界)之间查找ziggurat。而字符串满足这种条件。</P>
<P ALIGN="JUSTIFY"> 第二个例子没有完成匹配,为什么呢?因为在末尾的\W是正宽度断言,因此.必须匹配一个字符。但是在行未不是字符,而是一种条件。这是重要的区别。</P>
<P ALIGN="JUSTIFY"> 更进一步讲,在第二个例子中即使实现了匹配,那么正则表达式引擎会消去涉及到的字符。因此,如果输入如下代码:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="JUSTIFY"> $ziggurautString = " This matches the word zigguraut now";</P>
<P ALIGN="JUSTIFY"> $ziggurautString =~ s" \Wzigguraut\W" " g;</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"> 最后得到的结果是 This matches the wordnow。原因是已经把单词和插入的空格替换掉了。因而:</P>
<P ALIGN="JUSTIFY"> ·零宽度断言,例如\b\B能匹配没有字符的地方。它们在匹配的过程中不会去掉任一字符。下面是关于通配符匹配的其他例子:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="JUSTIFY"> $example = ' 111119';</P>
<P ALIGN="JUSTIFY"> $example =~ m" \d\d\d"; # match the first three digits it 
  can find in the string Matches ' 111'.</P>
<P ALIGN="JUSTIFY"> $example = ' This is a set of words and not of numbers';</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3> </FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1> 
<P ALIGN="JUSTIFY"> $example =~ m" of (\w\w\w\w\w)"; # Matches ' of words' ..Creates 
  a backreference</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"> 请注意最后一个例子,该列中,因为在字符串的开头有一个of(在words前面),所以模式匹配器会匹配这个特定的of。而不会去匹配后面的of(在numbers前面的那个)。最后一例也展示了我们将讨论论的问题。这就是如果想匹配五个单词字符的话,那么必须打印五次\w,这样就很烦恼。因此、为了便于匹配长模式,Perl提供了多重匹配运算符。我们接下来讨论这个问题。</P>
<P ALIGN="JUSTIFY"> 2.多重匹配运算符</P>
<P ALIGN="JUSTIFY"> PerI中有六个多重匹配运算符。主要用于避免编写重复代码,例如上一节提到的在一行中声明\w五次。渎者可把它们看作是速记的捷径。</P>
<P ALIGN="JUSTIFY"> PerI的六个多重匹配运算符是:</P>
<P ALIGN="JUSTIFY"> ·*——匹配零次,一次或多次。 ·?——匹配一次或者多次。</P>
<P ALIGN="JUSTIFY"> ·?——匹配零次或者一次。</P>
<P ALIGN="JUSTIFY"> ·{X}——匹配‘X’次。</P>
<P ALIGN="JUSTIFY"> ·{X,}——匹配‘X’或者更多次。</P>
<P ALIGN="JUSTIFY"> ·{X,Y}——匹配‘X’到‘Y’次。</P>
<P ALIGN="JUSTIFY"> 这里有两个等价的例子,但是哪个易读呢?</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="JUSTIFY"> $example = ' This is a set of words and not of numbers';</P>
<P ALIGN="JUSTIFY"> $example =~ m" of (\w\w\w\w\w)"; # Matches ' of word'.</P>
<P ALIGN="JUSTIFY"> $example =~ m" of (\w{5})"; # Usage of {X} form. Matches 5 
  characters,</P>
<P ALIGN="JUSTIFY"> # and backreference $1 becomes the string ' words'.</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"> 读者可能发现第二个例子的代码易读。这个例子使用了多重匹配运算符来避免写重复、讨厌的代码。第二个例子也用符号来匹配不定数量的字符。正则表达式a*匹配”,a,aa或者aaa,或任意数量的a。也就是匹配零个或多个a,例如:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="JUSTIFY"> $example = ' this matches a set of words and not of numbers';</P>
<P ALIGN="JUSTIFY"> $example =~ m" of(\w+)";</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"> 匹配的是字符串words(of(\w+) eq of words),又如:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="JUSTIFY"> $example =~ m" of (\w(2,3))"; # Usage of {X,Y}. Matches the 
  string ' wor'</P>
<P ALIGN="JUSTIFY"> # (the first three letters of the first match it finds.</P>
<P ALIGN="JUSTIFY"> matches the string ' wor' (' of \w{2,3}' equals ' of wor' 
  here)</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"> 与直觉相反.下面代码中的m" "子句:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="JUSTIFY"> $example = ' this matches a set of words and not of numbers';</P>
<P ALIGN="JUSTIFY"> $example =~ m" of(\d*)";</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"> 匹配该字符串,尽管我们正在用\d*来查找数字。什么原因呢?因为\d*表现为零个到多个,所以表达式匹配零个数字!然而:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="JUSTIFY"> $example =~ m" of(\d+)";</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"> 将不会匹配相同的字符串,因为表达式使用的是\d+而不是\d*。这样就意味着查找字符串中位于单词of后面的一个或多个数字,而这种条件是这个字符串不具有的。</P>
<P ALIGN="JUSTIFY"> 3.贪婪</P>
<P ALIGN="JUSTIFY"> 到目前为止,上面所有的例子陈述主要的一点是正则表达式引擎如何按给定的表达式匹配给定的字符串。即缺省情况下,多重匹配运算符是贪婪地。</P>
<P ALIGN="JUSTIFY"> “贪婪”在这里是什么含义呢?“贪婪”意味着在缺省状态下,Perl的多重匹配运算符能捕获一个字符串中的最大数量的字符,同的仍然有能力来完成模式匹配。读者应掌握好这一点。理解了贪婪的Perl表达式的本质会节省大量时间,以免跟踪古怪的正则表达式行为。</P>
<P ALIGN="JUSTIFY"> 这里有几个简单的关于贪婪行为的例子,例子中的贪婪行为能使程序员发疯。让我们从下面的语句开始:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="JUSTIFY"> $example = ' This is the best example of the greedy pattern 
  match in Perl5';</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"> 假定在该例中想匹配is。相应地,要编写如下代码:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="JUSTIFY"> $example =~ m # This (.*) the#;</P>
<P ALIGN="JUSTIFY"> print $1; # This does NOT print out the string ' is'!</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"> 读者希望打印$1时看到的是is。但是所得到的是下面的字符串:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="JUSTIFY"> ' is the best example of'</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY">程序的工作过程如图 9-6 所示。</P>
<P ALIGN="CENTER"><IMG SRC="images/Image8.jpg" WIDTH=510 HEIGHT=342></P>
<P ALIGN="JUSTIFY"> 造成这种结果的原因是多重匹配运算符*的贪婪。运算符*取得所有的字符直到最后出现的字符串the(在greedy前的一个)。那么如果读者不小心,则在使用正则表达式后得到不可预料结果。</P>
<P ALIGN="JUSTIFY"> 这里有更多例子:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="JUSTIFY"> $example = ' sam I am';</P>
<P ALIGN="JUSTIFY"> $example =~ m" (.*)am'; # matches the string ' sam I'</P>
<P ALIGN="JUSTIFY"> $example = ' RECORD: 1 VALUE: A VALUE2: B';</P>
<P ALIGN="JUSTIFY"> $example =~ m".RECORD';(.*)VALUE"; # matches ' 1 VALUE: A';</P>
<P ALIGN="JUSTIFY"> $example = ' RECORD';</P>
<P ALIGN="JUSTIFY"> $example =~ m" \w{2,3}"; # matches REC</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"> 最后一例显示出甚至数字多重匹配运算符也是贪婪的。虽然在RECORD中有两个单词字符,但是PerI更愿匹配三个,原因是它有这个能力。如果输入' 
  RE' =~ m" \w{2,3}",则只能匹配两个字符,因为这是可能匹配的最大数量。</P>
<P ALIGN="JUSTIFY"> 4.回溯和多重通配符</P>
<P ALIGN="JUSTIFY"> 好吧,已经准备很久了.现在到处理棘手题目的时候了。正如前面说过的,通配符和回溯的结合使正则表达式有极其缓慢的性能。如果读者理解了其中的原因,那么这是读者正“得到” 
  正则表达式的好标志。</P>
<P ALIGN="JUSTIFY"> 看以下例子:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1> 
<P ALIGN="JUSTIFY"> $string =~ m " has(.*)multiple(.*)wildcards";</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3> 
<P ALIGN="JUSTIFY"> 这意味着正则表达式将查找(以数字顺序):</P>
<P ALIGN="JUSTIFY"> 1)模式has(m" has.*multiple.*wildcards")。</P>
<P ALIGN="JUSTIFY"> 2)正则表达式能发现的最大文本直到它到达最后的multiple(m" has(.*)mMltiple(.*)</P>
<P ALIGN="JUSTIFY"> wildcards)。</P>
<P ALIGN="JUSTIFY"> 3)字符串multiple(m" has(.*)multiple(.*)wildcards")。</P>
<P ALIGN="JUSTIFY"> 4)能发现的最大文本直到遇到最后的wildcards(m" has(.*)multiple(.*)wildcards")。</P>
<P ALIGN="JUSTIFY"> 5)字符串wildcards(m" has(.*)multiple(.*)wildcards")。</P>
<P ALIGN="JUSTIFY"> 接着考虑一下,使用以下的模式将会发生什么:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1> 
<P ALIGN="JUSTIFY"> has many multiple wildcards multiple WILDCARDS</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3> 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -