首页
Preview

使用示例清晰解释正则表达式

照片由 Bryan NatanaelUnsplash 上提供。

这篇博客文章源于我对正则表达式(regex)的沮丧和回避,这种情况持续了很长一段时间。

数月来,我一直拖延学习正则表达式的想法,因为说实话,它们看起来非常令人生畏,尤其是当你第一次遇到它们时。我的意思是,一串字符连在一起,似乎没有任何逻辑可言 —— 没有人有时间处理这些东西!

直到最近我在工作中接到了一项任务,需要从字符串中检索元素,我才真正认识到正则表达式的威力。而事实证明,一旦你理解了基础知识,它其实并不那么糟糕。

因此,在本文中,我将解释什么是正则表达式,介绍一些基本的正则表达式字符,最重要的是,使用几个实际示例演示如何使用 R 编程语言执行正则表达式。具体来说,我们将讨论正则表达式中捕获组的概念。

如果你更喜欢 Python,可以在我的 GitHub 上找到代码的 Python 版本 这里

什么是正则表达式?

正则表达式既不是库,也不是编程语言。相反,正则表达式是一系列字符,它们指定了任何给定文本(字符串)中的搜索模式。

文本可以包含从字母到数字、从空格字符到特殊字符的任何东西。只要字符串遵循某种模式,正则表达式就足够强大,能够捕获该模式并返回字符串的特定部分。

你需要了解的基本正则表达式字符

现在,在我们深入了解细节之前,我认为首先重要的是我们先了解一些正则表达式的基础知识。

本文稍后的示例将建立在这里阐述的一些主要概念上,即:字符、分组和量词。

字符

  • 转义字符:\
  • 任何字符:.
  • 数字:\d
  • 非数字:\D
  • 字符或数字:\w
  • 非字符或数字:\W
  • 空格:\s
  • 非空格:\S
  • 字边界:\b
  • 非字边界:\B
  • 字符串开头:^
  • 字符串结尾:$

分组

  • 匹配方括号内的字符:[ ]
  • 匹配不在方括号内的字符:[^ ]
  • 或:|
  • 捕获组:( )

量词

  • 0 或更多:*
  • 1 或更多:+
  • 0 或 1:?
  • 精确数量的字符:{ }
  • 字符数量范围:{最小值,最大值}

正则表达式示例

不要担心,如果你现在还不理解上面的正则表达式字符 —— 它们只是我们即将讨论的示例的参考。

在本节中,我们将关注 6 个不同的示例,这些示例将有助于加强你对正则表达式的理解。实际上,我们将关注:

  • 2 个数字示例(电话号码和日期)
  • 2 个字母示例(姓名和 URL)
  • 2 个数字和字母的示例(电子邮件地址和地址)

在开始之前,请确保已安装并加载了 tidyverse 包。

1. 电话号码

假设我们有一个名为 phone 的数据框,其中包含如下电话号码列表:

我们希望将这些电话号码分解为 3 个单独的组件:区号(前 3 个数字)、交换机(接下来的 3 个数字)和线路号码(最后的 4 个数字)。

正如我们所看到的,这里的数字模式并不总是一致的,即它们具有不一致的括号、连字符和空格。然而,借助正则表达式的帮助,我们可以轻松地捕获数字组。

首先,我们需要定义一个正则表达式模式。

pattern <- "\\(?\\d{3}\\)?[[:punct:]]?\\s?\\d{3}[[:punct:]]?\\d{4}"

我们如何逐步解释这个模式?我们一步一步来,从左到右:

  • .? 0 或 1 个字符,以适应可选的左括号
  • (\\d{3}) 3 个数字字符(第一个捕获组,即前 3 个数字)
  • .* 0 或更多个字符,以适应可选的右括号、连字符和空格字符
  • (\\d{3}) 3 个数字字符(第二个捕获组,即接下来的 3 个数字)
  • .* 0 或更多个字符,以适应可选的连字符和空格字符
  • (\\d{4}) 4 个数字字符(第三个捕获组,即最后的 4 个数字)

然后,我们可以使用 str_match 函数使用我们定义的正则表达式模式检索捕获组,并将它们放入数据框中的单独列中。

library(tidyverse)

phone %>%
  mutate(matches = str_match(number, pattern)) %>%
  mutate(area_code = matches[, 2],
         exchange = matches[, 4],
         line_number = matches[, 6])

输出如下:

2. 日期

假设我们有另一个名为 date 的数据框,其中包含带有不一致分隔符的日期,我们想要提取天、月和年。

使用与我们刚才在电话号码中看到的非常相似的方法,我们需要首先定义一个正则表达式模式,然后将模式与原始日期列进行匹配,最后为每个捕获组创建一个新列。

首先,定义日期的正则表达式模式。

pattern <- "(\\d{2}).(\\d{2}).(\\d{4})"

代码解释:

  • (\\d{2}) 2 个数字字符(第一个捕获组,即天)
  • . 单个字符,用于考虑所有特殊字符
  • (\\d{2}) 2 个数字字符(第二个捕获组,即月)
  • . 单个字符,用于考虑所有特殊字符
  • (\\d{4}) 4 个数字字符(第三个捕获组,即年)``` 现在,我们可以匹配模式并为日期创建单独的列,包括日、月和年份。

3. 姓名

到目前为止,我们已经探索了两个只包含数字和特殊字符的字符串示例。现在让我们学习如何捕获单词和字母。

这里有一个名为“names”的数据框,包含人们的姓氏、头衔和名字。

让我们将它们分开,使它们各自拥有自己的单独列。

  • (\\w+) 一个或多个单词字符(第一个捕获组,即姓氏)
  • , 逗号字符
  • \\s 一个空格字符
  • (Mr|Ms|Mrs|Dr) 先生、女士、夫人或博士(第二个捕获组,即头衔)
  • .? 标题后面的0或1个句号字符
  • \\s 一个空格字符
  • (\\w+) 一个或多个单词字符(第三个捕获组,即名字)

现在,将它们放入单独的列中。

4. URL

让我们看另一个包含单词和字母的字符串示例。

到现在为止,你应该已经熟悉了这个过程。

  • (https?) http或https(第一个捕获组,即架构)
  • :// 特定的特殊字符串
  • (www)? 可选的www(第二个捕获组,即子域名)
  • .? 0或1个句号字符
  • (\\w+) 一个或多个单词字符(第三个捕获组,即二级域名)
  • . 一个句点字符
  • (\\w+) 一个或多个单词字符(第四个捕获组,即顶级域名)
  • /? 0或1个反斜杠字符
  • (\\w+)? 可选的一个或多个单词字符(第五个捕获组,即子目录)

将捕获组分成单独的列,我们得到:

5. 电子邮件地址

利用我们已经掌握的有关正则表达式的知识,现在让我们看看包含字母和数字的两个最终字符串示例。

假设我们在一个名为“email”的数据框中有一个电子邮件列表。

现在,生成一个正则表达式模式来匹配用户名、域名和域名。

  • ([a-zA-Z0-9\\_\\-\\.]+) 一个或多个小写字母、大写字母、数字和特殊字符,包括下划线、连字符和句点(第一个捕获组,即用户名)
  • @ 符号
  • ([a-zA-Z]+) 一个或多个小写和大写字母(第二个捕获组,即域名)
  • . 一个句点字符
  • (.+) 一个或多个字符(第三个捕获组,即域名)

然后,将此正则表达式模式应用于电子邮件列表:

6. 地址

当然,我留下了最好的例子供你参考。这个例子与我在工作中所做的相同。

为了重新创建那个工作片段,我创建了一个名为“address”的数据框,其中包含虚构地址。目标是检索房屋编号、街道名称、郊区、州和邮政编码。

像往常一样,我们需要首先定义一个正则表达式模式。

  • (\\d*) 0或多个数字字符,因为有些地址没有房屋编号(第一个捕获组,即房屋编号)
  • \\s? 0或1个空格字符
  • (.+) 一个或多个字符(第二个捕获组,即街道名称)
  • , 逗号
  • \\s 一个空格字符
  • (.+) 一个或多个字符(第三个捕获组,即郊区)
  • \\s 一个空格字符
  • ([A-Z]{2,3}) 2或3个大写字母(第四个捕获组,即州)
  • \\s 一个空格字符
  • (\\d{4}) 4个数字字符(第五个捕获组,即邮政编码)

将此模式与地址列表匹配,我们得到:

我希望通过本博客文章中演示的6个示例,你不仅能够更好地理解正则表达式的工作原理,更重要的是,能够欣赏其在匹配复杂字符串模式方面的灵活性。

译自:https://towardsdatascience.com/regular-expressions-clearly-explained-with-examples-822d76b037b4

版权声明:本文内容由TeHub注册用户自发贡献,版权归原作者所有,TeHub社区不拥有其著作权,亦不承担相应法律责任。 如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

点赞(0)
收藏(0)
alivne
复杂的问题简单化

评论(0)

添加评论