4.2. 这是一个表达式

未匹配的标注

4.2 这是一个表达式

你可能对计算器可以解释的那种表达式很熟悉,看下面的算术表达式:

2 + 4

“二加四”是由几个常数或字面量值和一个运算符组成。一个计算程序必须识别,比如,2 是一个数字常量, + 代表一个运算符,而不是被解释为 “+” 这个字符。

一个表达式告诉电脑怎样去产生一个结果。虽然我们确实想要 2 加 4 的结果,但我们不会简单地告诉电脑返回一个6,我们指引电脑去对这个表达式估值,然后返回一个值。

一个表达式可以比 2 加 4 要复杂得多。事实上它可以由多个简单的表达式组成。比如下面这个:

2 + 3 * 4

一个计算器通常是从左到右的对表达式求值。然而,然而特定运算符的优先级比其它的要高,那就是说它们会先运算。因此上面的表达式的结果为 14 而不是20。因为乘法优先于加法,可以通过将简单的表达式放在括号中来覆盖优先级。因此括号 “(2 + 3) * 4” 或者 2 加 3 的和乘4将会等于20。小括号() 是指引计算器改变表达式求值顺序的符号。

相反,正则表达式描述了一个模式或字符序列,连结是每个正则表达式隐含的基本操作。那就是说一个模式匹配邻近的字符,看下面的正则表达式:

ABE

正则表达式中的每个字面量字符只匹配单个字符。这个表达式描述了“一个 A 紧接着是一个 B 再接着是一个E”,或者简单地说是“字符串 ABE”。“字符串”这个术语意味着每个字符连接它前面的那个字符。一个正则表达式描述一个字符序列,这件事怎么强调都不为过。(新手倾向于在较高层次的单位比如单词上想问题,而不是在单独的字符上。)正则表达式是大小写敏感大写的,“A” 不匹配 “a” [^1]。

grep 这种接收正则表达式的程序,必须首先评估正则表达式的语法去产生一个模式,然后一行一行地去读取输入,努力匹配这个模式。一个输入行是一个字符串,然后看这个字符串是不是匹配这个模式。一个程序比较字符串中的第一个字符和模式中的第一个字符,如果匹配,那么就比较字符串的第二个字符和模式中的第二个字符。一旦不匹配,那么就从字符串的下一个字符从头开始进行匹配。图 3-1 展示了这个努力对一个输入行去匹配模式 “ABE“ 的过程。

image-20221018183218747

正则表达式不限于字面量的字符。比如有一个元字符 .,可以被用作是一个通配符去匹配任何一个单一字符。你可以认为通配符就像是拼字游戏里面的一个空白的卡片,意味着是任何一个字母。因此我们可以指定正则表达式 ”“A.E”,然后它将匹配 “ACE”,“ABE”,”ALE“ 等等。它将在 A 后面的那个位置匹配任何一个字符。

元字符 *,用来匹配 0 次或者多次出现的之前的正则表达式——通常是一个单字符。你可能对 * 比较熟悉,因为它是一个 shell 的元字符,意味着 ”0 或者多个字符“。但是这个含义和正则表达式中的 * 是非常不同的。元字符* 本身并不匹配任何东西,它修改了它之前的那个东西。正则表达式 .* 匹配任意数量的字符。然而在 shell 里面,* 就已经有这个含义了。(比如在 shell 里, ls * 会把当前目录里面的所有文件列出来。)正则表达式 A.*匹配任何匹配 A.E 的字符串,但它还匹配在 A 和 E 当中任何数量的字符。比如 ”AIRPLANE“,”A FINE“,”AFFABLE“,”A LONG WAY HOME“ 。注意”任何数量的字符“甚至可以是0!

如果你理解在正则表达式里面 .* 的区别,你就已经懂得了两个的基本类型的元字符:能被求值为一个单一字符的类型,以及修改前面的那个字符的求值方式的类型。

很明显,使用元字符,你可以扩展或者限制可能的匹配。你对哪些匹配,哪些不匹配有更多的控制。

脚注

脚注1

其它的一些使用正则表达式的程序提供了大小写不敏感的选项,但 sed 和 awk 并没有提供这个选项。

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

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


暂无话题~