4.12. 字符介绍——字符的重复出现

未匹配的标注

4.12 字符介绍——字符的重复出现

  • )元字符表明之前的正则表达式可能出现零次或多次。也就是说,如果它修饰的是单个字符,这个字符可能在那里也可能不在,假如它在的话,那么可能会多于一个,你可以用 元字符来匹配一个可能会出现在括号中的单词。

□"*hypertext"*□

“hypertext” 这个单词不管它是否出现在括号中都会被匹配。

➜  tmp.ihxdIAAP echo "hypertext" | grep '"*hypertext"*'
hypertext
➜  tmp.ihxdIAAP echo '"hypertext"' | grep '"*hypertext"*'
"hypertext"

如果被 * 修饰的字面字符确实存在,就可能不止一次地出现。比如让我们看一系列的数字:

1
5
10
50
100
500
1000
5000

正则表达式:

[15]0*

就会匹配所有的行。

➜  tmp.ihxdIAAP echo "1
5
10
50
100
500
1000
5000" | grep '[15]0*'
1
5
10
50
100
500
1000
5000

然而下面这个正则表达式

[15]00*

将会匹配除了前两行的所有行。

➜  tmp.ihxdIAAP echo "1
5
10
50
100
500
1000
5000" | grep '[15]00*'
10
50
100
500
1000
5000

第一个 0 是一个字面量,第二个被 * 修饰,意味着它可能存在,也可能不存在。一个相似的技术被用来匹配连续的空格。因为你通常想要匹配一个或者多个,而不是零个或者多个括号,你可以使用下面的这个来做。

□□*

当前置一个点(.)元字符,这个 * 元字符匹配任意数量的字符。它能用来在两个固定的字符串之间识别一段字符串。如果你想匹配在括号内的任意字符,你可以指定:

".*"

这将匹配这行上的第一个和最后一个括号之间的所有字符再加上括号。被 “.*” 匹配的这一段总是尽可能长。这个现在看起来不是很重要,但是一旦你学到替换匹配的字符串时,就会很重要了。

还有一个例子,一对尖括号是包裹用于标记语言如 SGML,HTML 和 Ventura Publisher 的格式指令的一种通用标记。你可以通过如下指定来打印有这些标记的所有行:

➜  tmp.ihxdIAAP grep '<.*>' sample
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
</body>
</html>

当用来修饰一个字符类时, * 可以匹配任意数量的这个类中的一个字符。比如,看下面这个五行的例子文件:

I can do it
I cannot do it
I can not do it
I can’t do it
I cant do it

如果我想匹配否定语句的每一个格式,而不是肯定语句,下面的正则表达式将会完成这个工作:

can[ no’]*t
  • 使得在这个类里面的任意字符以任意顺序,任意出现次数被匹配,结果如下:
➜  tmp.ihxdIAAP grep "can[ no’]*t" sample2
I cannot do it
I can not do it
I can’t do it
I cant do it

有四行匹配,错过一行——肯定语句。注意,假如正则表达式要匹配在字符串 “can” 和 “t” 之间的任意数量的字符,比如像下面这样:

can.*t

那它就将匹配到所有行。

➜  tmp.ihxdIAAP grep 'can.*t' sample2
I can do it
I cannot do it
I can not do it
I can’t do it
I cant do it

匹配某个东西的零或多次的能力,在技术术语里叫做闭包。被 egrep 和 awk 使用的扩展元字符集提供了几种闭包的变形,非常有用。 + 匹配之前的正则表达式的一次或更多次的出现。我们之前匹配一个或多个空格的那个例子可以简化为下面这个:

□+
  • 元字符能被认为是之前字符的至少一次出现。事实上很多人认为 * 才是这样工作的。

    ? (?)匹配 0 个或一次出现。比如在之前的例子里,我们使用一个正则表达式去匹配“80286”,“80386”,“80486”。如果我们还想匹配 “8086”,我们可以使用一个能被 egrep 和 awk 使用的正则表达式:

80[234]?86

它匹配了字符串80,紧接着是 “2”,“3”,“4” 或者没有字符,然后再是字符串 “86”。不要将正则表达式里面的 ? 和 shell 里面的 ? 通配符混淆。 shell 里面的 ? 代表了一个单字符,等价于正则表达式里面的里面的 .

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~