2041_22T2.Q1

数据结构分析

目标文件 awards.psv 为管道符分隔的文本文件(Pipe-Separated Values),每行包含 6 个字段,结构如下:
Award Name | Award Year | Winner Name | Winner Gender | Winner Country | Winner Birth Year


题解

Question 1: 提取澳大利亚籍获奖者

需求: 匹配 Winner Country 字段为 Australia 的行。

命令实现:

1
grep 'Australia' awards.psv

Question 2: 提取获得 ACM 图灵奖的女性

需求: 匹配 Award NameACM Turing AwardWinner GenderFemale 的行。

命令实现:

1
grep 'ACM Turing Award.*Female' awards.psv

原理解析:
此题涉及跨列组合查询。在纯 grep 环境下,需要利用通配符跨越中间的无关字段。

  1. ACM Turing Award:静态字面量匹配,定位起始特征。
  2. .*:贪婪匹配模式。. 代表任意单个字符,* 代表重复 0 次或多次。该组合会让正则引擎吞噬掉首列与性别列之间所有的字符(包括年份和姓名部分)。
  3. Female:静态字面量匹配。正则引擎在吞噬字符后,会通过回溯(Backtracking)寻找 Female 字符串以完成整个模式的闭环。

Question 3: 提取出生年份在 1990 至 1999 年间(含)的获奖者

需求: 匹配 Winner Birth Year 字段在 1990-1999 范围内的行。

命令实现:

1
grep '199[0-9]$' awards.psv

原理解析:
此题考察字符类(Character Classes)与尾部锚点(End-of-line Anchor)的结合。

  1. 199:匹配年份的前三位静态数值。
  2. [0-9]:字符集合,指示正则引擎在此位置匹配 0 到 9 之间的任意单个数字。这精确覆盖了 1990 到 1999 的区间需求。
  3. $:行尾锚点。强制断言上述模式必须出现在文本流的绝对末尾。因为 Winner Birth Year.psv 文件的最后一列,使用 $ 可以从空间复杂度上避免误匹配到中间列可能出现的 199x 数字序列。

Question 4: 提取 First name, Last name 和 Middle initial 首字母相同的获奖者

需求: 校验 Winner Name 字段,要求该姓名的名、中间名首字母和姓的首字母具有严格的字符一致性。

命令实现:

1
grep -E '\|([A-Z])[^ ]* \1\.? \1[^|]*\|' awards.psv

原理解析:
本题是纯正则环境下的高级应用。标准的有限状态自动机(DFA)无法处理前后文状态强相关的匹配逻辑,必须引入带有回溯机制的 NFA 引擎特性:捕获组(Capture Groups)反向引用(Backreferences)

执行逻辑拆解:

  1. -E:开启扩展正则表达式(ERE),减少转义符的使用,提升语句可读性。
  2. \|:匹配字段分隔符 |,将匹配作用域严格限定在 Winner Name 字段的起始位置。
  3. ([A-Z])核心状态保存。定义第一个捕获组(Group 1),匹配 First name 的首个大写字母。正则引擎会将匹配到的字符值(如 AM)写入内存临时栈中。
  4. [^ ]*:匹配 First name 的剩余字符,直到遇到空格。使用非空格字符集 [^ ] 能够兼容带有连字符的姓名变体。
  5. \1核心状态校验。反向引用内存中的 Group 1。引擎在此处强制校验当前字符是否与前面捕获的首字母在 ASCII 码上完全一致。对应 Middle initial 的匹配。
  6. \.?:匹配 Middle initial 后可选的缩写点号 .? 控制 0 或 1 次出现),以及后续的空格。
  7. \1:再次调用反向引用,强制校验 Last name 的首字母必须与前文一致。
  8. [^|]*\|:匹配 Last name 的剩余内容,直到遇到下一个字段分隔符 |,实现字段右侧的边界闭合,防止越界匹配。