Python - 匹配多行文本块的正则表达式

文章目录

    • 编写正则表达式以匹配多行字符串的原因
    • 匹配多行字符串的可能解决方案
      • Python re.compile() 方法
      • Python re.search() 方法
      • Python re.finditer() 方法
      • Python re.findall() 方法
      • Python re.MULTILINE 方法
      • Python 正则表达式符号
      • 使用 re.compile() 匹配 Python 中的多行文本块
      • 使用 re.findall() 在 Python 中匹配多行文本块


本文讨论了在多行字符串中搜索特定模式的方法。 该解决方案折衷了已知和未知模式的几种方法,并解释了匹配模式的工作原理。


编写正则表达式以匹配多行字符串的原因

假设我们有以下文本块:

Any compiled body of information is known as a data set. Depending on the situation's specifics, this may be a database or a simple array.\n
\n
IBM first used the term "data set," which meant essentially the same thing as "file," to describe a collection of related records.

从上面给出的文本块中,需要找到起始文本,文本在下面几行呈现。 重要的是要注意 \n 表示换行符而不是文字文本。

总而言之,我们想要跨多行查找和匹配文本,忽略文本之间可能出现的任何空行。 在上述文本的情况下,它应该返回 Any compiled body… 行,并且 IBM 首先在单个正则表达式查询中使用了 term… 行。


匹配多行字符串的可能解决方案

在讨论这个特定问题的解决方案之前,必须了解 regex(正则表达式)API 的不同方面,尤其是那些在整个解决方案中经常使用的方面。

那么,让我们从 re.compile() 开始吧。

Python re.compile() 方法

re.compile() 将正则表达式模式编译为正则表达式对象,我们可以使用该对象与 match()、search() 和其他描述的方法进行匹配。

re.compile() 相对于未编译模式的优势之一是可重用性。 我们可以多次使用已编译的表达式,而不是为每个未编译的模式声明一个新字符串。

import re as regex

pattern = regex.compile(".+World")
print(pattern.match("Hello World!"))
print(pattern.search("Hello World!"))

输出:

<re.Match object; span=(0, 11), match='Hello World'>
<re.Match object; span=(0, 11), match='Hello World'>

Python re.search() 方法

re.search() 在字符串中搜索匹配项,如果找到则返回一个 Match 对象。

如果存在多个匹配项,我们将返回第一个实例。

我们也可以不使用re.compile()直接使用,适用于只需要查询一次的情况。

import re as regex

print(regex.search(".+World", "Hello World!"))

输出:

<re.Match object; span=(0, 11), match='Hello World'>

Python re.finditer() 方法

re.finditer() 匹配字符串中的模式并返回一个迭代器,该迭代器为所有非重叠匹配项提供 Match 对象。

然后我们可以使用迭代器迭代匹配项并执行必要的操作; 匹配按照它们在字符串中从左到右的找到方式排序。

import re as regex

matches = regex.finditer(r'[aeoui]', 'vowel letters')
for match in matches:
    print(match)

输出:

<re.Match object; span=(1, 2), match='o'>
<re.Match object; span=(3, 4), match='e'>
<re.Match object; span=(7, 8), match='e'>
<re.Match object; span=(10, 11), match='e'>

Python re.findall() 方法

re.findall() 返回字符串中模式的所有非重叠匹配项的列表或元组。 从左到右扫描一个字符串。 并且匹配按照它们被发现的顺序返回。

import re as regex
 
# Find all capital words
string= ',,21312414.ABCDEFGw#########'
print(regex.findall(r'[A-Z]+', string))

输出:

['ABCDEFG']

Python re.MULTILINE 方法

re.MULTILINE 的一个显着优势是它允许 ^ 在每一行的开头而不是仅在字符串的开头搜索模式。

Python 正则表达式符号

当以复杂的方式使用时,正则表达式符号很快就会变得非常混乱。 以下是我们解决方案中使用的一些符号,以帮助更好地理解这些符号的基本概念。

  • ^ 断言行首的位置
  • 字符串匹配(区分大小写的)字符“字符串”
  • . 匹配所有字符(用于行终止的符号除外)
    • 尽可能频繁地匹配先前给定的标记。
  • \n 匹配换行符
  • \r 匹配一个 (CR) 回车符
  • ? 与前一个标记匹配 0-1 次
  • +? 尽可能少地匹配前一个标记 1 到无限次。
  • a-z 匹配 a 和 z 之间范围内的单个字符(区分大小写)

使用 re.compile() 匹配 Python 中的多行文本块

让我们了解使用不同的模式。

示例代码:

import re as regex

multiline_string = "Regular\nExpression"
print(regex.search(r'^Expression', multiline_string, regex.MULTILINE))

输出:

<re.Match object; span=(8, 18), match='Expression'>

上面的表达式首先断言它在行首的位置(由于 ^),然后搜索“表达式”的确切出现。

使用 MULTILINE 标志确保检查每一行是否出现“表达式”,而不仅仅是第一行。

示例代码:

import re as regex

data = """Any compiled body of information is known as a data set. Depending on the situation's specifics, this may be a database or a simple array.\n
\n
IBM first used the term "data set," which meant essentially the same thing as "file," to describe a collection of related records.
"""

result = regex.compile(r"^(.+)(?:\n|\r\n)+((?:(?:\n|\r\n?).+)+)", regex.MULTILINE)

print(result.search(data)[0].replace("\n", ""))

输出:

Any compiled body of information is known as a data set. Depending on the situation's specifics, this may be a database or a simple array.IBM first used the term "data set," which meant essentially the same thing as "file," to describe a collection of related records.

正则表达式可以分解并简化为更小的块以提高可读性:

在第一个捕获组 (.+) 中,每个字符都在行中匹配(除了与行终止符对应的任何符号); 这个过程尽可能频繁地进行。

之后,在非捕获组 (?:\n|\r\n) 中,尽可能多地匹配一个行结束符或者一个行结束符加回车。

至于第二个捕获组 ((?:(?:\n|\r\n?).+)+,它由一个非捕获组 (?:(?:\n|\r\n? ).+)+ 换行符或换行符加回车最多匹配一次。

每个字符都在非捕获组之外匹配,不包括行终止符。 尽可能多地执行此过程。

示例代码:

import re as regex

data = """Regex In Python

Regex is a feature available in all programming languages used to find patterns in text or data.
"""

query=regex.compile(r"^(.+?)\n([\a-z]+)",regex.MULTILINE)

for match in query.finditer(data):
    topic, content = match.groups()
    print ("Topic:",topic)
    print ("Content:",content)

输出:

Topic: Regex In Python
Content: 
Regex is a feature available in all programming languages used to find patterns in text or data.

上面的表达式可以解释如下:

在第一个捕获组 (.+?) 中,尽可能少地匹配所有字符(除了行终止符,和以前一样)。 之后,匹配单个换行符 \n

匹配换行符后,在第二个捕获组 (\n[a-z ]+) 中进行如下操作。 首先,匹配换行符,然后尽可能多次匹配 a-z 之间的字符。

使用 re.findall() 在 Python 中匹配多行文本块

示例代码:

import re as regex

data = """When working with regular expressions, the sub() function of the re library is an invaluable tool.

the subroutine looks over the string for the given pattern and applies the given replacement to all instances where it is found.
"""

query = regex.findall('([^\n\r]+)[\n\r]([a-z \n\r]+)',data)

for results in query:
    for result in results:
        print(result.replace("\n",""))

输出:

When working with regular expressions, the sub() function of the re library is an invaluable tool.
the subroutine looks over the string for the given pattern and applies the given replacement to all instances where it is found

为了更好地理解正则表达式的解释,让我们按每个组对其进行分解,看看每个部分的作用。

在第一个捕获组 ([^\n\r]+) 中,尽可能多地匹配所有字符,不包括换行符或回车符。

之后,当字符是表达式 [\n\r] 中的回车符或换行符时进行匹配。

在第二个捕获组 ([a-z \n\r]+) 中,a-z 或换行符或回车符之间的字符尽可能多地匹配。

你可能感兴趣的:(Python,编程,python,正则表达式,开发语言)