原文: Simple RegEx tricks for beginners

一直想学习正则表达式但被它们的复杂性劝退了?在本文中,我将向你展示五个易于学习的正则技巧,你可以立即在你最喜欢的文本编辑器中开始使用它们。

文本编辑器设置

虽然现在几乎所有文本编辑器都支持正则表达式,但我将在本教程中使用 Visual Studio Code。你可以使用任何你喜欢的编辑器。另外,请注意,你通常需要在搜索输入附近的某处打开 RegEx。这是在 VS Code 中执行此操作的方法:

GjEq59Gj7Io7MWY4OuayOCmqZo0f5ezXyvOS
You need to enable RegEx by checking this option

1) . 匹配任何字符

让我们从简单的开始。点符号 . 匹配任何字符:

b.t
tMEDSKS2mHfOfqYTQP-elCZI5OnGUObC484v

上面的 RegEx 匹配 "bot”"bat” 和任何其他以 b 开头并以 t 结尾的三个字符的单词。但是如果你想搜索点符号,你需要用 \ 对其进行转义,所以这个 RegEx 只会匹配精确的文本 "b.t"

b\.t
anNgoajLGzpFhPWYRnVGlowi0bL4Z4xni59R

2) .* — 匹配任何字符

这里 . 表示“任何字符”,* 表示“此符号之前的任何内容重复任意次数”。它们一起(.*)表示“任何符号任意次数”。例如,你可以使用它来查找以某些文本开头或结尾的匹配项。假设我们有一个带有以下签名的 JavaScript 方法:

loadScript(scriptName: string, pathToFile: string)

我们想要找到这个方法的所有调用,其中 pathToFile 指向文件夹 “lua” 中的任何文件。你可以为此使用以下正则表达式:

loadScript.*lua

这意味着,匹配所有以 “loadScript” 开头的文本,然后是最后一次出现的 “lua”

wCWC964KLZKxEHdW0fZlr4Z-X-vdcbYX-ogk
loadScript.*lua: matches everything starting with "loadScript" and ending in "lua"

3) ? — 非贪婪匹配

.* 后面的 ? 和其他一些 RegEx 序列之后的符号表示“尽可能少地匹配”。如果你查看上一张图片,你会看到文本 “lua” 在每次匹配中出现两次,并且匹配到第二个 “lua” 的所有内容。如果你想将所有内容匹配到第一次出现的 "lua",你将使用以下正则表达式:

loadScript.*?lua

这意味着,匹配以 "loadScript" 开头的所有内容,然后是第一次出现的 "lua"

1660810429783

4) ( ) $ — 捕获组和反向引用

好的,现在我们可以匹配一些文本。但是如果我们想改变我们找到的部分文本呢?为此,我们经常不得不使用捕获组。

假设我们更改了 loadScript 方法,现在它突然需要在两个参数之间插入另一个参数。让我们将这个新参数命名为 id,因此新函数签名应该是 loadScript(scriptName, id, pathToFile)。我们不能在这里使用文本编辑器的普通替换功能,但正则表达式正是我们所需要的。

hRdlYnNzYuX64kcVoXrvtH2RfwaY3FzNZedD
loadScript\(.*?,.*?\)

上面你可以看到运行以下正则表达式的结果:

loadScript\(.*?,.*?\)

这意味着:匹配以 "loadScript(" 开头的所有内容,然后是第一个 , 之前的任何内容,然后是第一个 ) 之前的任何内容。

唯一对你来说可能看起来很奇怪的是 \ 符号。它们用于转义括号。

我们需要对符号 () 进行转义,因为它们是 RegEx 用来捕获部分匹配文本的特殊字符。但是我们需要匹配实际的括号字符。

在前面的 RegEx 中,我们用 .*? 定义了方法调用的两个参数。符号。让我们通过在它们周围添加 ( 和 ) 符号来使我们的每个参数成为一个单独的捕获组:

loadScript\((.*?),(.*?)\)

如果你运行这个正则表达式,你会发现没有任何改变。这是因为它匹配相同的文本。但是现在我们可以将第一个参数称为 $1,将第二个参数称为 $2。这可被称为反向引用,它将帮助我们做我们想做的事情:在调用中间添加另一个参数。

搜索输入:

loadScript\((.*?),(.*?)\)

这意味着与之前的正则表达式相同,但将参数分别映射到捕获组 1 和 2。

替换输入:

loadScript($1,id,$2)

这意味着将每个匹配的文本替换为文本 “loadScript(“,后跟捕获组 1、“id”、捕获组 2 和 )。请注意,你不需要在替换输入中转义括号。

w27UNrc7N2hkWAO1DmU6p0gulIYiwU-oYjpT
替换结果

5) [ ] — 字符类

你可以通过在这些字符周围放置 [] 符号来列出要在特定位置匹配的字符。例如,class [0-9] 匹配从 0 到 9 的所有数字。你也可以显式列出所有数字:[0123456789] ——含义相同。你也可以将破折​​号与字母一起使用,[a-z] 将匹配任何小写拉丁字符,[A-Z] 将匹配任何大写拉丁字符,而 [a-zA-Z] 将匹配两者。

你也可以在字符类之后使用 *,就像在 . 之后一样,在这种情况下,这意味着:匹配该类中出现的任意数量的字符。

2aTqw0lDyht0cE1gqoF3O5eYcemyzhIBhSzU
expect.*to.equal\([0–9]*\):仅匹配我们期望被测变量等于数字的那些行

总结

你应该知道有几种正则表达式风格。我在这里讨论的是 JavaScript RegEx 引擎。大多数现代引擎都是相似的,但可能存在一些差异。通常,这些差异包括转义字符和反向引用标记。

我建议你立即打开文本编辑器并开始使用其中的一些技巧。你将看到自己现在可以比以前更快地完成许多重构任务。如果你对这些技巧感到满意,你就可以开始更多地研究正则表达式

感谢你阅读这篇文章。如果你觉得它有帮助,请将它分享给更多人。