正则表达式的可视化指南
在自然语言处理 (NLP) 中,根据模式检查文本或从文本中提取符合特定模式的部分是一项常见任务。正则表达式 (regex) 是实现此任务的强大工具。
正则表达式虽然功能强大,但它可能会让人望而生畏,因为它带有许多需要记住的功能和子部分。
在本文中,我将阐述正则表达式的各种底层概念。目标是帮助你建立一个良好的思维模型,理解正则表达式的工作原理。
心智模型
让我们从一个简单的例子开始,我们试图在文本中找到“cool”这个词。
使用正则表达式,我们可以简单地输入单词“cool”作为模式,它就会匹配该单词。
'cool'
虽然正则表达式匹配到了我们想要的单词“ cool ”,但它的操作方式不是在单词级别,而是在字符级别。这是关键思想。
关键思想:正则表达式在字符级别起作用,而不是单词级别。
这意味着正则表达式r'cool'
也会匹配以下句子。
基本构建块
现在我们理解了关键思想,让我们了解如何使用正则表达式匹配简单字符。
a. 特定字符
我们只需在正则表达式中指定字符,它就会匹配文本中的所有实例。
例如,下面给出的正则表达式将匹配文本中所有“a”的实例。您可以使用任何小写字母和大写字母。
'a'
您还可以使用 0 到 9 之间的任意数字,它同样有效。
'3'
请注意,正则表达式默认区分大小写,因此以下正则表达式将不会匹配任何内容。
'A'
b.空白字符
我们可以使用特殊的转义序列检测特殊字符,例如空格和换行符。
除了上述常见的之外,我们还有:
- \r表示回车
- \f换页
- \e表示转义。
c.特殊序列
正则表达式提供了一组内置特殊符号,可以一次匹配一组字符。这些符号以反斜杠 开头\
。
图案:\d
它匹配 0 到 9 之间的任何个位数。
注意,匹配项都是个位数。因此,下面有 4 个不同的匹配项,而不是一个数字18.04
。
模式:\s
它匹配任何空白字符(空格、制表符或换行符)。
模式:\w
它匹配任何小字母(a 到 z)、大写字母(A 到 Z)、数字(0 到 9)和下划线。
图案: 。
它匹配除换行符 (\n) 之外的任何字符。
import re
>>> re.findall(r'.', 'line 1\nline2')
['l', 'i', 'n', 'e', ' ', '1', 'l', 'i', 'n', 'e', '2']
模式:否定
如果您使用上述模式的大写版本,它们将起到否定的作用。
例如,如果“\d”匹配从 0 到 9 的任意数字,那么“\D”将匹配除“0 到 9”之外的任何数字。
d.字符集
[
这些是以 开头和结尾的模式,]
并指定应匹配的字符,用括号括起来。
例如,以下模式匹配任意字符“a”、“e”、“i”、“o”和“u”。
\d
您还可以复制使用以下模式的功能。它将匹配 0 到 9 之间的任何数字。
我们可以使用 来指定起始和结束数字,而不是指定所有数字-
。因此,除了[0123456789]
,我们还可以这样做:
例如,[2-4]
可用于匹配 2 到 4 之间的任意数字,即(2 或 3 或 4)。
你甚至可以在括号内使用我们之前学过的特殊字符。例如,你可以匹配 0 到 9 之间的任意数字或空格,如下所示:
下面,我列出了一些有用的常见模式及其含义。
e. 锚点
Regex 还具有特殊的处理程序,使模式仅当位于字符串的开头或结尾时才匹配。
我们可以使用^
锚点来匹配仅在行首的模式。例如:
类似地,我们可以在字符后使用$
锚点来匹配行尾的模式。例如:
f. 转义元字符
考虑一下我们想要完全匹配单词“斯塔克先生”的情况。
如果我们编写一个像这样的正则表达式Mr. Stark
,那么它将产生意想不到的效果。因为我们知道点在正则表达式中具有特殊含义。
因此,如果我们的目标是匹配精确的字符本身,我们应该始终转义诸如等.
特殊元字符。$
以下是元字符列表,如果您直接使用它们,则应该记住对其进行转义。
^ $ . * + ? { } [ ] \ | ( )
基本块的重复
现在我们可以对任何字符进行模式匹配,我们可以重复一些事情并开始构建更复杂的模式。
a. 幼稚的重复
仅使用我们目前所学的知识,一个简单的方法就是重复这个模式。例如,我们可以通过重复字符级模式来匹配两位数。
\d\d
b.量词
正则表达式提供了特殊的量词来指定其前面的字符的不同重复类型。
i. 固定重复
我们可以使用{...}
量词来指定模式应重复的次数。
例如,先前匹配 2 位数字的模式可以重新创建为:
您还可以使用相同的量词指定重复范围。例如,要匹配从 2 位到 4 位的数字,我们可以使用以下模式:
当应用于句子时,它将匹配 4 位数字和 2 位数字。
笔记:
最小计数和最大计数之间不应有任何空格,例如,\d{2, 4} 不起作用。
ii. 灵活量词
Regex 还提供量词“*”、“+”和“?”,使用它们可以指定字符的灵活重复。
-
0 次或 1 次:如果
?
量词?
重复 0 次或 1 次,则匹配前一个字符。这在使某些部分可选时很有用。例如,假设我们想匹配单词“sound”和“sound”,其中“s”是可选的。那么,我们可以使用
?
量词,当字符重复0次或1次时匹配。 -
一次或多次:如果
+
量词+
重复 1 次或多次,则它与前一个字符匹配。例如,我们可以使用正则表达式找到任意长度的数字
\d+
。 -
零次或多次:如果
*
量词*
重复零次或多次,则它与前一个字符匹配。
Python 中的用法
Python 在标准库中提供了一个名为“re”的模块来处理正则表达式。
需要原始字符串
要在 Python 中指定正则表达式,我们在它前面加上r来创建原始字符串。
pattern = r'\d'
为了理解为什么我们在前面加上r ,让我们尝试打印不带 的表达式\t**r**
。
>>> pattern = '\t'
>>> print(pattern)
您可以看到,当我们不使用原始字符串时,\t
Python 会将该字符串视为制表符的转义字符。
现在我们把它转换成原始字符串。我们得到我们指定的内容。
>>> pattern = r'\t'
>>> print(pattern)
\t
使用 re 模块
要使用re
模块,我们可以先导入re
模块,如下所示:
import re
1. re.findall
此函数允许我们将所有匹配项作为字符串列表获取。
import re
re.findall(r'\d', '123456')
['1', '2', '3', '4', '5', '6']
2. 重新匹配
此函数在字符串的开头搜索模式,并返回第一个匹配项作为匹配对象。如果未找到该模式,则返回 None。
import re
match = re.match(r'batman', 'batman is cool')
print(match)
<re.Match object; span=(0, 6), match='batman'>
使用匹配对象,我们可以得到匹配的文本
print(match.group())
batman
如果我们的模式不在句子的开头,我们将不会得到任何匹配。
import re
match = re.match(r'batman', 'The batman is cool')
print(match)
None
3. 重新研究
此函数同样会查找某个模式的首次出现,但该模式可以出现在文本中的任何位置。如果未找到该模式,则返回 None。
import re
match = re.search(r'batman', 'the batman is cool')
print(match.group())
batman
参考
- AM Kuchling,“正则表达式 HOWTO - Python 3.9.0 文档”
连接
如果您喜欢这篇博文,欢迎通过Twitter与我联系,我每周都会在那里分享新的博文。
文章来源:https://dev.to/amitness/a-visual-guide-to-regular-expression-i3