正则表达式并不难

2025-06-08

正则表达式并不难

正则表达式是那种只有在需要的时候才会学习的东西。除非你正在处理大量数据,否则你很可能不会用到它。

这是否意味着,作为一名软件工程师,我们应该把它忘掉,等到真正需要的时候再去担心它?难道我们不应该承担起学习它的责任吗?

程序员们觉得正则表达式很难。就像所有技能一样,掌握它需要练习。为了帮助你,我写了这篇文章,涵盖了正则表达式的基础知识,并展示了一个简单的应用来说明如何使用它。

内容

  • 学习正则表达式的理由
  • 理解正则表达式
  • 正则表达式结构和特殊字符
  • 使用 Regex 和 JavaScript 的示例
  • 资源

学习正则表达式的理由

陷入困境,只能在谷歌上搜索我们试图解决的问题的正则表达式模式。这听起来熟悉吗?我敢打赌你们中至少有一个人以前遇到过类似的情况。但是,你不觉得了解正则表达式的来龙去脉会更容易吗?事实上,这确实可以减少搜索答案的时间。

正则表达式提供了一种更简洁的方法来解决需要某种解析的问题。split 函数就是一个例子。在应用某种逻辑之前,将字符串转换为 token 的过程非常冗长。事实证明,与使用正则表达式相比,这种实现方式存在局限性。

希望下一部分能让您感到兴奋,因为我们将介绍更多有关正则表达式的内容。

理解正则表达式

正则表达式(Regular Expression)又称规则表达式。它是一组字符串字符,用于定义所需数据模式的表达式。它自 20 世纪 80 年代以来就已存在,主要用于搜索和解析字符串。

用于查找具有“ .com”域的电子邮件地址的正则表达式示例可以是:/.+@.+\.com/

如果现在不明白,别担心。下一部分我会讲解上面表达式中各个字符的含义。

正则表达式结构和特殊字符
首先要知道的是,定义正则表达式模式有两种方法:
使用常规字符串文字

var pattern = /abc/

调用 RegExp 构造函数

var pattern = new RegExp('abc')

何时使用哪个?常规字符串字面量适用于预先知道模式的情况。相反,在运行时使用动态数据时,可以使用 RegExp 构造函数。

正则表达式中的特殊字符扩展了创建更复杂正则表达式模式的能力。让我们来看看一些基本的字符。

以下每种情况都会用到字符串“From: dinys18@dinmon.tech ”。为了得到正则表达式的结果,我们会使用箭头。但这在 JavaScript 中绝对行不通。

^- 插入符号匹配字符串的开头

var re = /^ From: / => From:

$- 美元符号匹配字符串的结尾

var re = /tech$/ => tech

.- 句点字符匹配任意单个字符

var re = /.@/ => s@ // Any single character and @ sign

[0-9]- 字符集。匹配括号内的任何字符。

var re = /[0-9]/ => 1 and 8, not to be confused by 18

*- 星号字符匹配其前面的任意字符,至少一个,即零个或一个。

var re = /.*:/ => From: // Any multiple of character until semi column

+- 加号字符可匹配其前面的任意字符一次或多次。

var re = /@[a-z]+/ => dinmon // Start at @ sign, include any multiple of lowercase characters

最后,星号、加号和句点等字符在正则表达式中属于特殊字符。如果您想在正则表达式中使用它们,该怎么办呢?幸运的是,有一种方法可以在模式中使用特殊字符,但您需要对它们进行转义。也就是说,\在它们前面添加(斜杠),这样它们就不再被视为特殊字符,而是被视为常规字符。

var re = /\..*/ => .tech // Start at the period character, include any characters afterwards

我们已经介绍了构建正则表达式的各种方法,现在让我们将其与 JavaScript 结合起来。这将使我们能够执行更复杂的操作,例如提取、替换等等。

使用 Regex 和 JavaScript 的示例

在本节中,我将介绍如何使用正则表达式与 JavaScript 结合对字符串进行提取。为此,我将实现一个允许创建重复文件夹名称的文件模拟器。

因此,为了避免文件夹名称重复,我们需要在文件夹名称后附加一个字符串,以确保新文件夹的名称唯一。为此,我们将添加一个用括号括起来的索引,以表示文件夹重复的次数。

在我们开始构建正则表达式之前,让我们先分解一下要处理的各种情况:
文件夹名称包含任意字符,例如 python
文件夹名称包含任意字符和括号中的数字,例如 python (0)

首先,我们需要获取重复文件夹的名称(包含任何字符)。

var regex = /.+/

然后查找带有数字的括号。

var regex2 = /\([0-9]+\)/

您会注意到,我们用斜线转义了数字周围的两个括号。在括号中间,我们使用了从 0 到 9 的字符集来定义数字。由于我们需要多个数字,因此我们添加了加号,以适应两位或两位以上的数字。

这听起来不错,但在我们试图传递的单个字符串上使用两个正则表达式会不会很冗余?如果我们能在一行代码中做到这一点会怎么样?为了实现这一点,我们将使用花括号提取文件夹的名称和编号。

最终的表达式将如下所示:

var regex = /(.+) \(([0-9]+)\)/

要执行正则表达式,请使用上述表达式作为参数调用匹配函数。

var name = 'Folder (0)'
var matchFound = name.match(regex) => ['Folder (0)', 'Folder ', '0']

如果未找到任何值或提取的值,则上述 match 函数的结果将返回 null。有关更多详细信息,请参阅match()函数参考。

注意:数组的第一个值将是您传入的字符串,其余的是提取的值。

我把下一部分留给你去完成,以便函数 getDuplicateName 返回文件夹的名称和文件夹末尾的索引(如果它是重复的)。

function getDuplicateName(list, name) {
            var regex = /(.+) \(([0-9]+)\)/  
            var matchFound = name.match(regex) ?? []

            var [, baseName, index] = matchFound;

            var isDone = (matchFound.length > 0) ? !(!!baseName) : !list.includes(name) 
            var count = index ? Number(index) + 1 : 0
            var newName = name
            baseName = baseName ?? name

            while (!isDone) {
                newName = `${baseName} (${count})` 
                if (!list.includes(newName)) {
                    isDone = true
                    continue
                }
                count++
            }

            return newName
        }

资源

如果您想查看完整的源代码,请访问GitHub 存储库文件模拟器的演示。

屏幕截图-模型(3).png

如果您喜欢阅读的内容,请考虑在Twitter上关注以查找有价值的内容。

鏂囩珷鏉ユ簮锛�https://dev.to/dinmon/regex-isn-t-that-hard-2kcf
PREV
我用 React、Redux 和 Typescript 制作了一个 Spotify 克隆版
NEXT
完全开放地创建一家初创公司