本文讨论了在多行字符串中搜索特定模式的方法。 该解决方案折衷了已知和未知模式的几种方法,并解释了匹配模式的工作原理。
假设我们有以下文本块:
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()
开始吧。
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'>
re.search()
在字符串中搜索匹配项,如果找到则返回一个 Match 对象。
如果存在多个匹配项,我们将返回第一个实例。
我们也可以不使用re.compile()直接使用,适用于只需要查询一次的情况。
import re as regex
print(regex.search(".+World", "Hello World!"))
输出:
<re.Match object; span=(0, 11), match='Hello World'>
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'>
re.findall()
返回字符串中模式的所有非重叠匹配项的列表或元组。 从左到右扫描一个字符串。 并且匹配按照它们被发现的顺序返回。
import re as regex
# Find all capital words
string= ',,21312414.ABCDEFGw#########'
print(regex.findall(r'[A-Z]+', string))
输出:
['ABCDEFG']
re.MULTILINE
的一个显着优势是它允许 ^ 在每一行的开头而不是仅在字符串的开头搜索模式。
当以复杂的方式使用时,正则表达式符号很快就会变得非常混乱。 以下是我们解决方案中使用的一些符号,以帮助更好地理解这些符号的基本概念。
让我们了解使用不同的模式。
示例代码:
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 之间的字符。
示例代码:
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 或换行符或回车符之间的字符尽可能多地匹配。