正则表达式断言来实现分组捕获

案例

import re

text_ok = "是方案1#故障原因是xx#故障类型(一级)是xx#故障类型(二级)是xx类型(三级)是xx"
text_fail = "不能匹配的字符串"

pattern = r"(?:解决方案是(.*?))?#(?:故障原因是(.*?))?#(?:故障类型\(一级\)是(.*?))?#(?:故障类型\(二级\)是(.*?))?#?(?:故障类型\(三级\)是(.*?))?$"

matches = re.search(pattern, text_ok)
if matches:
    solution = matches.group(1) if matches.group(1) else ''
    reason = matches.group(2) if matches.group(2) else ''
    type_1 = matches.group(3) if matches.group(3) else ''
    type_2 = matches.group(4) if matches.group(4) else ''
    type_3 = matches.group(5) if matches.group(5) else ''
    print("解决方案:", solution)
    print("故障原因:", reason)
    print("故障类型(一级):", type_1)
    print("故障类型(二级):", type_2)
    print("故障类型(三级):", type_3)
else:
    print("匹配失败")


断言和分组捕获都是正则表达式的语法元素,用于匹配特定的模式。

1. 断言

断言是指一个位置的前面或后面必须满足一定的条件才能匹配成功。常用的断言有肯定/正向先行断言(positive lookahead)和否定/负向先行断言(negative lookahead)。

肯定/正向先行断言的语法为:`(?=pattern)`,表示要匹配的内容后面必须要满足pattern的条件,但匹配到的内容并不包括pattern。

否定/负向先行断言的语法为:`(?!pattern)`,表示要匹配的内容后面必须不满足pattern的条件。

例如,对于字符串"hello world",如果我们只需要匹配出"hello"这个单词,但不希望把"hello"这个单词后面的空格也包括进来,可以使用肯定先行断言,正则表达式为:`hello(?= )`,这表示只匹配"hello"后面紧跟着的一个空格字符。如果我们需要匹配所有不包括空格的字符,可以使用否定先行断言,正则表达式为:`[\S]+(?= )`,这表示匹配所有不包括空格的字符,直到遇到一个空格字符。

2. 分组捕获

分组捕获是指用一对括号将需要匹配的内容包起来,并将其作为一个分组,用于后续的引用或操作。分组捕获的语法为:`(pattern)`。

例如,对于字符串"abc123",如果我们想要分别匹配出"abc""123"这两个部分,可以使用分组捕获,正则表达式为:`(\w+)(\d+)`,这表示第一个分组匹配一个或多个字母/数字(即"abc"),第二个分组匹配一个或多个数字(即"123")。

分组捕获也可以用于匹配替换。例如,可以使用"(\w+), (\w+)"匹配"John, Smith"这个字符串,在匹配结果中第一个分组匹配到"John",第二个分组匹配到"Smith"。如果需要将"John Smith"这种格式的字符串改成"Smith, John"的格式,可以使用"\2, \1"这个替换表达式,其中\1表示第一个分组匹配到的内容,\2表示第二个分组匹配到的内容,即"Smith, John"
所谓断言,就是指明某个字符串前边或者后边,将会出现满足某种规律的字符串。

就拿匹配<title>xxx</title>标签来说,我们想要的是xxx,它没有规律,但是它前边肯定会有<title>,后边肯定会有</title>,这就足够了。

想指定xxx前肯定会出现<title>,就用正后发断言,表达式:(?<=<title>).*

想指定xxx后边肯定会出现</title>,就用正先行断言,表达式:.*(?=</title>)

两个加在一起,就是(?<=<title>).*(?=</title>)

这样就能匹配到xxx,匹配的内容不包括断言的内容,即完整的匹配就是xxx,不会包含<title></title>,子组中也不包含。

对正后发和正先行的解释:

其实掌握了规律,就很简单了,无论是先行还是后发,都是相对于xxx而言的,也就是相对于目标字符串而言。

假如目标字符串后边有条件,可以理解为目标字符串在前,就用先行断言,放在目标字符串之后。

假如目标字符串前边有条件,可以理解为目标字符串在后,就用后发断言,放在目标字符串之前。

假如指定满足某个条件,就是正。

假如指定不满足某个条件,就是负。

断言只是条件,帮你找到真正需要的字符串,本身并不会匹配!

!表示正好相反的意思,就是把=换成了!,看表格解释,X代表字符

(?=X )
零宽度正先行断言。仅当子表达式 X 在 此位置的右侧匹配时才继续匹配。例如,\w+(?=\d) 与后跟数字的单词匹配,而不与该数字匹配。此构造不会回溯。
(?!X)
零宽度负先行断言。仅当子表达式 X 不在 此位置的右侧匹配时才继续匹配。例如,例如,\w+(?!\d) 与后不跟数字的单词匹配,而不与该数字匹配 。
(?<=X)
零宽度正后发断言。仅当子表达式 X 在 此位置的左侧匹配时才继续匹配。例如,(?<=19)99 与跟在 19 后面的 99 的实例匹配。此构造不会回溯。
(?<!X)
零宽度负后发断言。仅当子表达式 X 不在此位置的左侧匹配时才继续匹配。例如,(?<!19)99 与不跟在 19 后面的 99 的实例匹配

你可能感兴趣的:(笔记,python,正则表达式)