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

📄 perlreg_8rule.html

📁 这是一个介绍 linux 编程知识的文章。
💻 HTML
📖 第 1 页 / 共 5 页
字号:
<P ALIGN="JUSTIFY"> 所发生的一切是:</P>
<P ALIGN="JUSTIFY"> 1)、Perl匹配has(i.e, m" has(.*)multiple(.*)wildcards);</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> 
<P ALIGN="JUSTIFY"> 2)Perl执行m" has(.*)multiple(.*)wildcards部分且吃掉它能够发现的所有字符,直到遇到最后的multiple,接着匹配:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1> 
<P ALIGN="JUSTIFY"> has many multipIe wildcards multiple WILDCARDS</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3> 
<P ALIGN="JUSTIFY"> 3)Perl匹配字符串multiple(即m" has(.*)multiple(.*)wildcards):</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> 
<P ALIGN="JUSTIFY"> 4)Perl试图发现字符串wildcards但是失败了,接着读出字符串的其余部分:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1> 
<P ALIGN="JUSTIFY"> WILDCARDS does not match ' wildcards' !</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3> 
<P ALIGN="JUSTIFY"> 5)现在Perl应做什么呢?因为有多个通配符(*),所以Perl回溯。正则表达式可能犯错的地方是在第2步,即当它吃掉:</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> 
<P ALIGN="JUSTIFY"> 时,因而,它正好返回到has后面:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1> 
<P ALIGN="JUSTIFY"> has many multiple wildcards multiple WILDCARDS</P>
<P ALIGN="JUSTIFY"> ^goes back here</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3> 
<P ALIGN="JUSTIFY"> 6)现在试图更正错误,仅捕获那些位于最后一个multiple之前的字符。因而,模式m"</P>
<P ALIGN="JUSTIFY">has(.*)multiple(.*)wildcards" 匹配:</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> 
<P ALIGN="JUSTIFY"> 7)在m" has(.*)multiple(.*)wildcards" 中的multiple随后匹配:</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> 
<P ALIGN="JUSTIFY"> 8)接着通配符匹配空格——m" has(.*)multiple(.*)wildcards")匹配:</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> 
<P ALIGN="JUSTIFY"> 9)最后,wildcards(m" has(.*)multiple(.*)wildcards")匹配:</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> 
<P ALIGN="JUSTIFY"> 因而整个正则表达式匹配has many multiple wildcards。它给出了预料结果,但是得到该结果肯定走了弯路。肯定地说,Perl实施正则表达式的算法有些捷径来提高性能,但是刚才给出的逻辑基本上是正确的。我毫不犹豫地认为这个例子是本章中最主要的一个——</P>
<P ALIGN="JUSTIFY">即使Perl高于有时也不能从语义上正确分祈正则表达式(很使他们恼火)。一遍又一遍地复习.直到充分理解结果。这之后,尽量按Perl的匹配方法跟踪以下代码:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1> 
<P ALIGN="JUSTIFY"> $pattern = " afbgchdjafbgche";</P>
<P ALIGN="JUSTIFY"> $pattern =~ m" a(.*)b(.*)c(.*)d";</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3> 
<P ALIGN="JUSTIFY"> 我们在此随意结出一个:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1> 
<P ALIGN="JUSTIFY"> afbgchdjafbgche (m" a(.*)b(.*)c(.*)d";)</P>
<P ALIGN="JUSTIFY"> afbgchdjafbgche (m" a(.*)b(.*)c(.*)d";) -- greedy, goes to 
  last ' b'</P>
<P ALIGN="JUSTIFY"> afbgchdjafbgche (m" a(.*)b(.*)c(.*)d";)</P>
<P ALIGN="JUSTIFY"> afbgchdjafbgche (m" a(.*)b(.*)c(.*)d";) -- matches g</P>
<P ALIGN="JUSTIFY"> afbgchdjafbgche (m" a(.*)b(.*)c(.*)d";)</P>
<P ALIGN="JUSTIFY"> afbgchdjafbgche (m" a(.*)b(.*)c(.*)d";) -- backtrack because 
  no ' d'</P>
<P ALIGN="JUSTIFY"> afbgchdjafbgche (m" a(.*)b(.*)c(.*)d";) -- now we take up 
  everything to the next to last b</P>
<P ALIGN="JUSTIFY"> afbgchdjafbgche (m" a(.*)b(.*)c(.*)d";)</P>
<P ALIGN="JUSTIFY"> afbgchdjafbgche (m" a(.*)b(.*)c(.*)d";) -- now the second 
  .* becomes greedy.</P>
<P ALIGN="JUSTIFY"> afbgchdjafbgche (m" a(.*)b(.*)c(.*)d";)</P>
<P ALIGN="JUSTIFY"> afbgchdjafbgche (m" a(.*)b(.*)c(.*)d";) -- still no d.darn.backtracks</P>
<P ALIGN="JUSTIFY"> afbgchdjafbgche (m" a(.*)b(.*)c(.*)d";) -- wildcard becomes 
  less greedy, gobbles to next to last c</P>
<P ALIGN="JUSTIFY"> afbgchdjafbgche (m" a(.*)b(.*)c(.*)d";)</P>
<P ALIGN="JUSTIFY"> afbgchdjafbgche (m" a(.*)b(.*)c(.*)d";) -- there is only one 
  d in the expression and this matches up to it</P>
<P ALIGN="JUSTIFY"> afbgchdjafbgche (m" a(.*)b(.*)c(.*)d";) -- a match! </P>
<P ALIGN="JUSTIFY"> matches ' afbgchd'.</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3> 
<P ALIGN="JUSTIFY"> 不是很标致,正如读者所看到的,如果读者有多个贪婪的多重匹配运算符,事情可能变得更糟,效率更低。也许从这个例子中得到的最简单的就是左边的多重匹配运算优先于右边的执行。下面这样的模式:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1> 
<P ALIGN="JUSTIFY"> m" (.*)(.*)";</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3> 
<P ALIGN="JUSTIFY">在一个没有换行符的字符串中,将总是使第一个反向引用包含整个字符串,而第二个却什么也没有。像这种错误最好使用-Dr命令行选项进行处理,就像在Perl 
  - Dr.script.p中一样。我们将在第21章讨论这一点。另外,如果读者不想有贪婪会发生什么?好吧,正如我们会在下节见到的,perl(与其他包不同)有能力处理字符的非贪婪形式。</P>
<P ALIGN="JUSTIFY"> 5.非贪婪多重匹配运算符</P>
<P ALIGN="JUSTIFY"> 贪婪可能是一件幸事,但是它也常会引起争论!举一个常用的C注释语句的例子(它是很平常的FAQ且是在文档中)。假定要匹配下面的粗体文本:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1> 
<P ALIGN="JUSTIFY"> /* this is a comment*/ /* another comment */</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3> 
<P ALIGN="JUSTIFY"> 这里试图找出一个贪婪方式的解决方法。我们想匹配后跟所有文本的/* 直到包括 */。如果我们尝试以下代码:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1> 
<P ALIGN="JUSTIFY"> m" /\*.*\*/";</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3> 
<P ALIGN="JUSTIFY"> 于是,将匹配:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1> 
<P ALIGN="JUSTIFY"> /* this is a comment*/ /* another comment */</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3> 
<P ALIGN="JUSTIFY"> 又一次因为是greedy形式所以匹配全部字符串。</P>
<P ALIGN="JUSTIFY"> 以下是笔者所能提供的最好的贪婪方式的解决办法:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1> 
<P ALIGN="JUSTIFY"> $commentmatcher =~ m" /\*([^*]*|\**[^/*])*\*/";</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3> 
<P ALIGN="JUSTIFY"> 它不是所有解决方法中最好读的。(我们可以使用m" "使之更易读,后面将讲到。)我们</P>
<P ALIGN="JUSTIFY">将在后面复习这点,因为理解了这个特殊表达式对在总体上掌握正则表达式有很大帮助!现在我们一起看看贪婪形式。对于非贪婪形式这里有一简单规则来记住它们:只要在一个贪婪多重运算符的后面添加?就可使之成为非贪婪。</P>
<P ALIGN="JUSTIFY"> 因而,前面的commentmatcher成为:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1> 
<P ALIGN="JUSTIFY"> $commentmatcher =~ m" /\*(.*?)\*/";</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3> 
<P ALIGN="JUSTIFY">这仍然不是最易读的形式,但是肯定比前面的要好!我们可以简单地描述这条语句如下:“取到/*,接着取最小数量的字符,再取结束的*/”,工作过程如图 
  9-7 所示。</P>
<P ALIGN="CENTER"><IMG SRC="images/Image9.jpg" WIDTH=433 HEIGHT=385></P>
<P ALIGN="JUSTIFY"> “懒惰”是用于描述?的另一术语。正则表达式引擎可以北认为是缓慢地前移,直到遇到第一个可匹配的表达式。在该例中,它正是遇到一个*/以后移到下一步骤。如果读者输入以下代码:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1> 
<P ALIGN="JUSTIFY"> $line =~ m" (.*?)(.*?)(.*?)";</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3> 
<P ALIGN="JUSTIFY"> 每个(.*?)符什么也不会匹配。什么原因呢?在这里匹配的最小数量的字符是零(因为读者已经输入*(零到多或全))。因而根据匹配零个字符的要求.每个(.*?)都完成自己的工作,且缓慢地把控制传到下一个(.*?),返过来它又取零个字符。下面是懒惰匹配程序的通用规则。只要向他们添加字符类(如.、\d、或[123]),就可得到懒惰行为:</P>
<P ALIGN="JUSTIFY"> ·*?——匹配零、一或多次,但匹配可能的最少次数。</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> </font></B><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="JUSTIFY">    $example = ‘This is the time for a11good man to come to 
  the aid of their party’ ;</P>
<P ALIGN="JUSTIFY">    $example = ~ m&quot; This (.*?) the&quot;;</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3> 
<P ALIGN="JUSTIFY">该例处配 ‘is’ ,如果它是贪婪地则会匹配 ‘ is the time for all good man to come 
  to’。</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1> 
<P ALIGN="JUSTIFY">    $example = ‘19992113333333333333331’;</P>
<P ALIGN="JUSTIFY">    if ($example = ~ m &quot; l (\d{3,}?)&quot; )</P>
<P ALIGN="JUSTIFY">    {</P>
<P ALIGN="JUS

⌨️ 快捷键说明

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