正则表达式

  1. IPv4
  2. 多行匹配
  3. 非捕获和命名组
  4. 对正则分组的替换

IPv4

  • 匹配每个值
^(\d|[1-9]\d|1\d\d|2(?:[0-4]\d|5[0-5]))\.(\d|[1-9]\d|1\d\d|2(?:[0-4]\d|5[0-5]))\.(\d|[1-9]\d|1\d\d|2(?:[0-4]\d|5[0-5]))\.(\d|[1-9]\d|1\d\d|2(?:[0-4]\d|5[0-5]))$
  • 只做验证判断
^(?:(?:\d|[1-9]\d|1\d\d|2(?:[0-4]\d|5[0-5]))\.){3}(?:\d|[1-9]\d|1\d\d|2(?:[0-4]\d|5[0-5]))$

多行匹配

当需要跨行匹配的时候,由于(.)不能匹配\n所以无法多行匹配

例如:

>>> comment = re.compile(r'/\*(.*?)\*/')
>>> text1 = '/* this is a comment */'
>>> text2 = '''/* this is a
... multiline comment */
... '''
>>>
>>> comment.findall(text1)
[' this is a comment ']
>>> comment.findall(text2)
[]
>>>

要修正这个问题,需要加一个非捕获组(?:.|\n)来将\n也包含进来

>>> comment = re.compile(r'/\*((?:.|\n)*?)\*/')
>>> comment.findall(text2)
[' this is a\n multiline comment ']
>>>

另外也可以使用re.DOTALL这个标志,它可以将(.)匹配任意字符,当然也就包含了\n,但是由于包含的信息更多,在复杂情况下可能会出现意想不到的情况,所以优先使用非捕获组的方式来解决这个问题。

非捕获和命名组

  • 非捕获的用法是(?:.*)
  • 命名组的用法是(?P<name>)

举个例子,要取一个IP:

import re
file = 'A_FOO_BAR_DR01_127.0.0.1_20220221180010.diag'
reg = r'(?P<name>\S+)\_(?P<ip>(?:\d+\.){3}(?:\d+)).*'

match = re.match(reg, file) print(match.group(name)) print(match['ip']) ## output: # A_FOO_BAR_DR01 # 127.0.0.1

对正则分组的替换

\g可以用来替换正则分组的内容,例如:

def pascal_case_to_snake_case(camel_case: str):
    """大驼峰(帕斯卡)转蛇形

>>> pascal_case_to_snake_case('HuaweiVrpDisplayVersion') 'huawei_vrp_display_version' """ snake_case = re.sub(r"(?P<key>[A-Z])", r"_\g<key>", camel_case) return snake_case.lower().strip('_')

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 365433079@qq.com