From 734ad269a6c777aec618250b534e7aab63b28a15 Mon Sep 17 00:00:00 2001 From: MirageTurtle <60972592+MirageTurtle@users.noreply.github.com> Date: Thu, 27 Aug 2026 16:03:44 +0800 Subject: [PATCH 1/2] docs(ch09): finalize regex chapter and add PCRE details --- docs/Ch09/index.md | 34 +++++++++++++++++++++------------- docs/Ch09/supplement.md | 5 ++--- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/docs/Ch09/index.md b/docs/Ch09/index.md index b7dd9c4d..e48f3ad6 100644 --- a/docs/Ch09/index.md +++ b/docs/Ch09/index.md @@ -4,8 +4,6 @@ icon: material/console # Shell 高级文本处理与正则表达式 -!!! Warning "本文已基本完稿,正在审阅和修订中,不是正式版本。" - !!! abstract "导言" 本章节将介绍一些常用的 shell 文本处理工具,它们可以帮助你更加得心应手地处理大量有规律的文本。 @@ -121,18 +119,18 @@ $ sort animals | uniq -c ### 特殊字符 {#special-char} | 特殊字符 | 描述 | -| --------------- | ---------------------------------------------------------------------------------------------------------- | -| `[]` | 方括号表达式,表示匹配的字符集合,例如 `[0-9]`、`[abcde]` | +|-----------------|------------------------------------------------------------------------------------------------------------| +| `[]` | 方括号表达式,表示匹配的字符集合。例如 `[0-9]`、`[abcde]` | | `()` | 标记子表达式起止位置 | | `*` | 匹配前面的子表达式零或多次 | | `+` | 匹配前面的子表达式一或多次 | | `?` | 匹配前面的子表达式零或一次 | -| `\` | 转义字符,除了常用转义外,还有:`\b` 匹配单词边界;`\B` 匹配非单词边界等 | +| `\` | 转义字符 | | `.` | 匹配除 `\n`(换行)外的任意单个字符 | | `{}` | 标记限定符表达式的起止。例如 `{n}` 表示匹配前一子表达式 n 次;`{n,}` 匹配至少 n 次;`{n,m}` 匹配 n 至 m 次 | | \| | 表明前后两项二选一 | | `$` | 匹配字符串的结尾 | -| `^` | 匹配字符串的开头,在方括号表达式中表示不接受该方括号表达式中的字符集合 | +| `^` | 匹配字符串的开头;在方括号表达式中表示不接受该方括号表达式中的字符集合 | 以上特殊字符,若是想要匹配特殊字符本身,需要在之前加上转义字符 `\`。 @@ -162,7 +160,7 @@ $ sort animals | uniq -c ter\b ``` -### 基本/扩展正则表达式 {#bre-ere} +### 基本、扩展与 Perl 兼容正则表达式 {#bre-ere-pcre} 基本正则表达式(Basic Regular Expressions, BRE)和扩展正则表达式(Extended Regular Expressions, ERE)是两种 POSIX 正则表达式风格。 @@ -170,6 +168,8 @@ BRE 可能是如今最老的正则风格了,对于部分特殊字符(如 `+` ERE 与如今的现代正则风格较为一致,相比 BRE,上述特殊字符默认发挥特殊作用,加上 `\` 之后表达普通含义。 +除 POSIX BRE/ERE 外,实际使用中还经常遇到 [PCRE(Perl Compatible Regular Expressions)](https://www.pcre.org/)。PCRE 在 ERE 类似语法的基础上提供了更多现代正则表达式功能,例如 `\d`、`\w`、非捕获分组 `(?:...)`、以及惰性匹配 `*?` 等(具体内容可阅读[拓展阅读](./supplement.md))。 + 具体的例子在下文介绍工具时可以看到。 !!! tip "帮助理解正则表达式的工具" @@ -182,25 +182,27 @@ ERE 与如今的现代正则风格较为一致,相比 BRE,上述特殊字符 grep 全称 Global Regular Expression Print,是一个强大的文本搜索工具,可以在一个或多个文件中搜索指定 pattern 并显示相关行。 -grep 默认使用 BRE,要使用 ERE 可以使用 `grep -E` 或 egrep。 +grep 默认使用 BRE,要使用 ERE 可以使用 `grep -E` 或 egrep,要使用 PCRE 可以使用 `grep -P`。 命令格式:`grep [option] pattern file` -一些用法: +常见参数: - `-n`:显示匹配到内容的行号 - `-v`:显示不被匹配到的行 - `-i`:忽略字符大小写 +- `-R`:递归搜索目录下的所有文件 ```console $ ls /bin | grep -n "^man$" # 搜索内容仅含 man 的行,并且显示行号 $ ls /bin | grep -v "[a-z]\|[0-9]" # 搜索不含小写字母和数字的行 $ ls /bin | grep -iv "[A-Z]\|[0-9]" # 搜索不含字母和数字的行 +$ ls /bin | grep -R "man" # 递归搜索 /bin 下所有文件中含有 man 的行 ``` ### sed {#sed} -sed 全称 Stream EDitor,即流编辑器,可以方便地对文件的内容进行逐行处理。 +sed 全称 Stream EDitor,即流编辑器,可以方便地对文件的内容进行逐行处理。sed 每次从文件中读取一行,然后使用指定的命令进行操作,操作完成后输出结果。 sed 默认使用 BRE,要使用 ERE 可以 sed -E。 @@ -213,9 +215,15 @@ $ sed [OPTIONS] -f scriptfile file(s) 此处的 command 和 scriptfile 中的命令均指的是 sed 命令。 +常见参数: + +- `-i`:直接修改文件内容,可以加上后缀 `-i[SUFFIX]` 备份原文件 +- `-n`:不自动输出每一行,通常和 p 命令配合使用,只输出被匹配到的行 + 常见 sed 命令: - s 替换 + - 格式为 `s/old/new/flag`,其中 `old` 和 `new` 分别为要替换的内容和替换后的内容(可以使用正则表达式),`flag` 可选,常用的有 `g`(全局替换)、`p`(打印匹配行)、`i`(忽略大小写),`/` 表示分隔符,常见的分隔符包括 `/`、`#`、`@`、`|`、`,`、`;`、`:`、`_`、`^`、`~`、`!` 等,若要使用分隔符本身,则需要加上转义符 `\`。 - d 删除 - c 选定行改成新文本 - a 当前行下插入文本 @@ -313,11 +321,11 @@ $ awk 'BEGIN { sum = 0 } { sum += $2 * $3 } END { print sum }' awk_demo 可以接受少许的误过滤(false positive)。 -!!! question "正则表达式练习 3:Vscode 中的文本批量替换" +!!! question "正则表达式练习 3:VS Code 中的文本批量替换" - Vscode 支持使用正则表达式语法查找与替换文本内容。有一天,你的项目中使用的某个函数更新了:调用方式从 `func1(a, b, c)` 变成了 `func1_new(c, b, a, null)`。其中假设 `a`、`b`、`c` 均为不含逗号的表达式。 + VS Code 支持使用正则表达式语法查找与替换文本内容。有一天,你的项目中使用的某个函数更新了:调用方式从 `func1(a, b, c)` 变成了 `func1_new(c, b, a, null)`。其中假设 `a`、`b`、`c` 均为不含逗号的表达式。 - 尝试写出搜索的正则表达式与替换目标表达式。提示:正则表达式中使用 `()` 包裹的为一组,在 vscode 的替换目标表达式中可以使用 `$1`、`$2` 的格式来引用第一组、第二组等内容。 + 尝试写出搜索的正则表达式与替换目标表达式。提示:正则表达式中使用 `()` 包裹的为一组,在 VS Code 的替换目标表达式中可以使用 `$1`、`$2` 的格式来引用第一组、第二组等内容。 !!! question "Shell 文本处理工具练习 1:文件内容替换" diff --git a/docs/Ch09/supplement.md b/docs/Ch09/supplement.md index f6e700a4..a7c44ba4 100644 --- a/docs/Ch09/supplement.md +++ b/docs/Ch09/supplement.md @@ -25,8 +25,7 @@ icon: material/puzzle 组号分配规则: - 0 代表整个表达式 -- 从左至右,按左括号的出现顺序分配,第一个为 1,第二个为 2,以此类推 -- 扫描两遍,第一次只分配未命名的组,第二次只分配命名的组。即任意命名组的组号都大于未命名的组号 +- 从左至右,按左括号的出现顺序分配,第一个为 1,第二个为 2,以此类推,命名组与未命名组共享同一编号序列,即命名组同样会占用一个数字组号 !!! example "示例" @@ -42,7 +41,7 @@ icon: material/puzzle `\b\w+(?=ing\b)` 可以匹配 `ing` 结尾的单词前面的部分。例如 `going` 中的 `go` 会被该正则匹配。 - `(?<=\bre)\w+\b` 可以匹配 `re` 开开头的单词的后面一部分。例如 `revue` 中的 `vue` 会被该正则匹配。 + `(?<=\bre)\w+\b` 可以匹配 `re` 开头的单词的后面一部分。例如 `revue` 中的 `vue` 会被该正则匹配。 ### 正则表达式的代价 {#ddos} From d031b2c48885087ab4d6b5c89ec0156172197f73 Mon Sep 17 00:00:00 2001 From: MirageTurtle <60972592+MirageTurtle@users.noreply.github.com> Date: Thu, 27 Aug 2026 16:30:54 +0800 Subject: [PATCH 2/2] fix: fix formatting with prettier --- docs/Ch09/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Ch09/index.md b/docs/Ch09/index.md index e48f3ad6..a465b6a5 100644 --- a/docs/Ch09/index.md +++ b/docs/Ch09/index.md @@ -119,7 +119,7 @@ $ sort animals | uniq -c ### 特殊字符 {#special-char} | 特殊字符 | 描述 | -|-----------------|------------------------------------------------------------------------------------------------------------| +| --------------- | ---------------------------------------------------------------------------------------------------------- | | `[]` | 方括号表达式,表示匹配的字符集合。例如 `[0-9]`、`[abcde]` | | `()` | 标记子表达式起止位置 | | `*` | 匹配前面的子表达式零或多次 |