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

📄 perlreg_8rule.html

📁 这是一个介绍 linux 编程知识的文章。
💻 HTML
📖 第 1 页 / 共 5 页
字号:
<P ALIGN="JUSTIFY"> $string =~ s" (b)\1(a..)\1\2" $1$2";</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"> $string =~ s" (b)b(all)ball" ball";</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"> 或者用行话讲,用bballball替换ball。 ’</P>
<P ALIGN="JUSTIFY"> 正则表达式看起来很像图 9-5 所示。</P>
<P ALIGN="CENTER"><IMG SRC="images/Image6.jpg" WIDTH=416 HEIGHT=418></P>
<P ALIGN="JUSTIFY"> </P>
<P ALIGN="JUSTIFY"> s" " "中有一些复杂的反向引用。如果理解了最后一个例子。那么读者在理解Perl的正则表达式如何工作方面远远走在了前面。反向引用可能而且确实会变得更糟。</P>
<P ALIGN="JUSTIFY"> 5.嵌套反向引用</P>
<P ALIGN="JUSTIFY"> 嵌套反向引用对于复杂的难以用单一顺序(一个字符串跟在另一个字符串后面)进行匹配的字符串作用明显。例如下面的表达式:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="JUSTIFY"> m" ((aaa)*)" ;</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"> 使用 * 来匹配多次出现的aaa:即匹配",aaa,aaaaaa,aaaaaaaaa。换句话说,Perl匹配一行中有多个3a的模式。但是这个模式不会匹配aa。假定想匹配如下的字符串:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="JUSTIFY"> $string = ' softly slowly surely subtly';</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"> $string = m" ((s...ly\s*)*)" ; # note nested parens.</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"> 在该例中,最外层的圆括号捕获全部字符串:softly slowly surely subtly 。最内层的圆括号捕获字符串的组合,这种组合是以s开头,以ly结尾且ly后跟空格形成的。因此,正则表达式先捕获surely,将其抛开,然后捕获slowly,将其抛开,然后捕获surely,最后捕获subtly。这里有一个问题,反向引用按什么顺序出现?读者可能在这个问题上很容易迷惑。是外层圆括号先出现呢,还是内层的内括圆号先出现?最简单的解决办法是记住以下三条原则:</P>
<P ALIGN="JUSTIFY"> 1)在表达式中,一个反向引用越在前,它对应的反向引用编号就越小。例如:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="JUSTIFY"> $var =~ m" (a)(b)";</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"> 该例中,反向引用(a)变为$1,(b)变成了$2。</P>
<P ALIGN="JUSTIFY"> 2)一个反向引用如果它包含范围越广,则它的反向引用编号就越小。例如:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="JUSTIFY"> $var =~ m" (c(a(b)*)*)";</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"> 该例中,包含全部内容(m "(c(a(b)*)*)" )的反向引用成为$1。有a嵌套在里面的表达式 m"(c(a(b)*)*)"成为$2。在(m"(c(a(b)*)*)" 
  )中带有b的嵌套表达式成为$3。</P>
<P ALIGN="JUSTIFY"> 3)在两个规则冲突的情况下,规则1优先。在语句$var =~ m" (a)(b(c))" 中,(a)成为$1,b(c)成为$2,(c)成为$3。</P>
<P ALIGN="JUSTIFY"> 因而,在这个例子中,(s...ly\s*)*成为$1,(s...ly\s*)*成为$2。</P>
<P ALIGN="JUSTIFY"> 注意这里有另一个问题。让我们一起返回到刚开始的复杂的正则表达式:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="JUSTIFY"> $string = 'softly slowly surely subtly'</P>
<P ALIGN="JUSTIFY"> $string = m"(((s...ly\s*)*)"; # note nested parens.</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3> 
<P ALIGN="JUSTIFY"> 这里(s...ly\s*)*匹配什么呢?它匹配多个字符串;首先是softly,接着是slowly,再接着是surely,最后是subtly。既然(s...ly\s*)*匹配多个字符串,那么Perl会抛弃掉第一个匹配而使$2成为subtly。</P>
<P ALIGN="JUSTIFY">即便有这些规则,嵌套圆括号仍然可能引起混乱。要做的最好事情就是实践。再一次用这些逻辑的不同组合去实现正则表达式,然后把它们交给Perl解释器。这样做可让读者明白反向引用是以什么次序被Perl解释器进行解释的。</P>
<B> 
<P ALIGN="JUSTIFY">&nbsp;</P>
<P ALIGN="JUSTIFY"><a name="6"></a>9.3.6 原则6</P>
</B> 
<P ALIGN="JUSTIFY"> 正则表达式的能力的核心在于通配符和多重匹配运算符。通配符运算符允许匹配字符串中的多个字符。如果正在处理二进制数据,那么通配符就匹配一系列字符。多重匹配运算符可匹配零个、一个或多个字符。就讲解Perl的基础而言,到目前为止我们所使用的例子都是带启发性的,但功能并不是很强大。实际上,渎者可能会用C子程序去完成它们中的任意—个。Perl 
  正则表达式集合的强大功能来自于其匹配文本的多模式能力,(即:通过前面提到的逻辑“速记法”来描述许多不向的数据模式)。Perl正好可提供最好的速记法。</P>
<P ALIGN="JUSTIFY"> 1.通配符</P>
<P ALIGN="JUSTIFY"> 通配符代表字符类。他没有如下字符串,但不知道他们是否大写:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1> 
<P ALIGN="JUSTIFY"> .Kumquat</P>
<P ALIGN="JUSTIFY"> .Kristina</P>
<P ALIGN="JUSTIFY"> .Kentucky</P>
<P ALIGN="JUSTIFY"> .Key</P>
<P ALIGN="JUSTIFY"> .Keeping</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"> 这种情况下,如下的Perl表达式会匹配每个单词的第一个字符:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="JUSTIFY"> [Kk]</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"> 这是字符类的一个例子。Perl中的所有通配符可以用括号[并把想匹配的字符类放在括号中最后加上结尾括号]这种方法表示。前面的通配符告诉正则表达式引擎"好,我正在这里查找"K"或者"R"。如果发现两者之一那么就匹配它”。下面是另一些使用通配符的例于:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="JUSTIFY"> $scalarName = ' this has a digit (1) in it';</P>
<P ALIGN="JUSTIFY"> $scalarName =~ m" [0-9]"; # This matches any character between 
  0 and 9, that is matches any digit.</P>
<P ALIGN="JUSTIFY"> $scalarName =~ 'this has a capital letter (A) in it';</P>
<P ALIGN="JUSTIFY"> $scalarName =~ m" [A-Z]"; # This matches any capital letter 
  (A-Z).</P>
<P ALIGN="JUSTIFY"> $scalarName =~ " this does not match, since the letter after 
  the string 'AN' is an A"</P>
<P ALIGN="JUSTIFY"> $scalarName =~ m" an[^A]";</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"> 前两个例子相当直观,[0-9]匹配this has a digit(1) in it中的数字1。[A—Z]匹配this 
  has acapital letter(A) in it中的大写字符A。最后一例稍有点技巧,因为在这个模式中仅有一个an,所以可能被匹配的字符唯有最后的四个字符,即an 
  A。</P>
<P ALIGN="JUSTIFY"> 然而,通过询问模式an[^A]我们已经明确地告诉正则表达式去匹配a,接着是n,空格,最后一个为非A的字符。因而,该例中没有完成匹配。如果给定模式为 
  match an A not an e,那么匹配就会完成,因为第一an被跳过后,第二个正好匹配!就像如下例子:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="JUSTIFY"> $scalarName = " This has a tab( ) or a newline in it so it 
  matches";</P>
<P ALIGN="JUSTIFY"> $scalarName =~ m" [\t\n]" # Matches either a tab or a newline.</P>
<P ALIGN="JUSTIFY"> # matches since the tab is present.</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"> 这个例子说明了用匹配和通配符可以做的一些有趣的事情。首先,读者已经在""字符串插入的相同字符也可以在正则表达式和用括号表示的字符类中([t\n])插入。其中"\t"匹配制表符,"\n"匹配换行符。</P>
<P ALIGN="JUSTIFY">其次.如果读者在[]里的开头部分放置一个^,则通配符会匹配非字符组中的字符。同样地,如果在[ ]中放置-,则通配符匹配给定的范围(在这个例子中是所有的数字[0-9]。所有的大写字母([A-Z])。这些运算符还可被合并,从而得到相当特别的通配符:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="JUSTIFY"> $a =~ m" [a-fh-z]"; # matches any lowercaes letter * except* 
  g.</P>
<P ALIGN="JUSTIFY"> $a =~ m" [^0-9a-zA-Z]"; # matches any nonword character. (i.e.,NOT</P>
<P ALIGN="JUSTIFY"> # a character in 0-9, a-z or A-Z)</P>
<P ALIGN="JUSTIFY"> $a =~ m" [0-9^A-Za-z]"; # a mistake, Does not</P>
<P ALIGN="JUSTIFY"> # equal the above. Instead matches 0-9,</P>
<P ALIGN="JUSTIFY"> $a =~ m" [\t\n]"; # matches a space character: tab, newline 
  or blank).</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"> </P>
<P ALIGN="JUSTIFY"> 需许意的重要地方是第三个例子,在[0—9^A—Za—z]中的插入记号是一个字面上的插入记号,而不是代表否定,原因是它在字符类的中间出现。因此,如果读者想得到一个否定的字符类。那么就总是要把插入记号放在[]开头。也不要忘记用[]。如果读者忘记了[],那么得到的将是一个字面上的文本字符串,而不是一个字符类。</P>
<P ALIGN="JUSTIFY"> (1)公用通配符</P>
<P ALIGN="JUSTIFY"> 碰巧某些通配符是公用的;当读者每次想匹配一个数字时,可能不愿意每次都必须要输入类似于[0-9]这样的代码。对于那些情况,Perl有几个方便的快捷通配符,使用它们后可使编程工作容易。下面是这些边配符以及它们代表的含义和它们对应的字符组合:</P>
<P ALIGN="JUSTIFY"> .\d — 匹配数字(字符组合[0-9])。</P>
<P ALIGN="JUSTIFY"> .\D — 匹配非数(字符组合[^0-9])。</P>
<P ALIGN="JUSTIFY"> .\w — 匹配单词字符(字符组合[a-zA-Z0-9_])(这里下划线算作一个单词字符)。</P>
<P ALIGN="JUSTIFY"> .\W — 匹配非单词字符(字符组合[^a-zA-Z0-9_])。</P>
<P ALIGN="JUSTIFY"> .\s — 匹配空格字符(字符组合[\t\n])(制表符、换行符、空格)。</P>
<P ALIGN="JUSTIFY"> .\S — 匹配非空格字符(字符组合[\t\n])。</P>
<P ALIGN="JUSTIFY"> .- 匹配任意字符(在某些情况下)换行符除外(字符组合[^\n])、当输入m"(.*)"S时匹配任意字符。参见本章后面的修饰符。</P>
<P ALIGN="JUSTIFY"> .$- 尽管它实际上并不是一个通配符(它不匹配任何具体字符).但它是广泛使用的特殊字符;如果将其放在正则表达式的尾部则它匹配“行尾”。零宽度断言。</P>
<P ALIGN="JUSTIFY"> .^- 尽管实际上不是一个通配符,但如果它位于正则表达式的开头则它是匹配“行首”的特殊字符。零宽度断言。</P>
<P ALIGN="JUSTIFY"> .\b,\B- 与$和^相同;不匹配字符,但匹配单词边界(\b)或匹配无单周边(\B)。零宽度断言。</P>
<P ALIGN="JUSTIFY"> 我们从表中注意到的第一点是“点”通配符(.)。它常与多重匹配运算符一道用于在条目间充当填充者。请看以下匹配:</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="JUSTIFY"> $a = ' NOW is the time for all good men to come to the aid 
  of their party';</P>
<P ALIGN="JUSTIFY">$a =~ m" (Now).*(party)"; # matches, since ' .' matches any 
</P>
<P ALIGN="JUSTIFY">character except newline </P>
<P ALIGN="JUSTIFY">and ' *' means match zero or more characters.</P>
</font></B><FONT FACE="宋体" LANG="ZH-CN" SIZE=3>
<P ALIGN="JUSTIFY"> *捕获位于Now和party中间的所有字符,匹配是成功的。(在这种环境下的“所有”意味着“零或者更多,尽可能多”。这就是所谓的贪梦(greediness);在我们后面谈到多重匹配运算时再谈它。)</P>
<P ALIGN="JUSTIFY"> 下面是通配符的一些其他例子。注意我们在=~的左边使用了单引用字符串(这是一个测试表达式的简单方法):</P>
</FONT><B><FONT FACE="宋体" LANG="ZH-CN" SIZE=1>
<P ALIGN="JUSTIFY"> 1 ' 1956.23' =~ m" (\d+)\.(\d+)"; # $1 = 1956, $2 = 23</P>
<P ALIGN="JUSTIFY"> 2 ' 333e+12' =~ m" (\D+)"; # $1 = ' e+'</P>
<P ALIGN="JUSTIFY"> 3 ' $hash($value)' =~ m" \$(\w+){\$(\w+)}"; # $1 = ' hash', 
  $2 = 'value'</P>
<P ALIGN="JUSTIFY"> 4 ' $hash($value)' =~ m" \$(\w+){(\w)*(\w+)(\w*)}"; # $1 = 
  ' $', $2 = ' hash',</P>
<P ALIGN="JUSTIFY"> # $3 = ' $', $4 = ' value'</P>
<P ALIGN="JUSTIFY"> 5 ' VARIABLE = VALUE' =~ m" (\w+)(\s*) = (\s*)(\w+)"; # $1 
  = ' VARIABLE', #$2 = ' ',</P>
<P ALIGN="JUSTIFY"> # $3 = ' ', $4 = ' VALUE'</P>

⌨️ 快捷键说明

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