社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

【Python】100个Python正则表达式技巧,让你从入门到精通

机器学习初学者 • 7 月前 • 332 次点击  

掌握 Python 正则表达式:100个实用技巧与案例。

Structural Pattern Matching in Python I

正则表达式(regex 或 regexp)是 Python 中用于模式匹配与文本处理的强大工具。其语法简洁灵活,能够精准描述字符串中的各类模式,在数据提取、格式验证、文本清洗等场景中发挥着重要作用。

本文系统梳理了 Python 正则表达式的高级特性与一系列使用技巧,帮助读者快速掌握!

一、特性

1.正则表达式简介

正则表达式是定义搜索模式的字符序列,是用于字符串匹配和处理的多功能工具。在 Python 中,re 模块提供了对正则表达式的支持。

import re

2.基本模式

2.1 字面字符

pattern = re.compile(r'hello')
result = pattern.match('hello world')
print(result.group())  # 输出:'hello'

2.2 字符类

pattern = re.compile(r'[aeiou]')
result = pattern.findall('hello world')
print(result)  # 输出:['e', 'o', 'o']

2.3 通配符 .

pattern = re.compile(r'he..o')
result = pattern.match('hello world')
print(result.group())  # 输出:'hello'

3.量词

3.1 *+?

pattern = re.compile(r'ab*c')
result = pattern.match('ac')
print(result.group())  # 输出:'ac'

4.锚点

4.1 ^(字符串开头)和 $(字符串结尾)

pattern = re.compile(r'^hello')
result = pattern.match('hello world')
print(result.group())  # 输出:'hello'

5.字符转义

pattern = re.compile(r'\d+')  # 匹配一个或多个数字
result = pattern.match('123')
print(result.group())  # 输出:'123'

6.字符集和范围

pattern = re.compile(r'[a-z]')
result = pattern.findall('Hello World')
print(result)  # 输出:['e', 'l', 'l', 'o', 'o', 'r', 'l', 'd']

7.分组和捕获

pattern = re.compile(r'(\d+)-(\d+)-(\d+)')
result = pattern.match('2023-11-25')
print(result.groups())  # 输出:('2023', '11', '25')

8.高级模式

8.1 前瞻和后顾

pattern = re.compile(r'(?<=@)\w+')
result = pattern.findall('user@example.com')
print(result)  # 输出:['example']

8.2 非捕获组

pattern = re.compile(r'(?:\d+)-(\d+)-(\d+)')
result = pattern.match('2023-11-25')
print(result.groups())  # 输出:('11', '25')

9.Python 中正则表达式的使用

9.1 match 与 search

pattern = re.compile(r'world')
result = pattern.match('hello world')
print(result)  # None


result = pattern.search('hello world')
print(result.group())  # 输出:'world'

9.2 findall

pattern = re.compile(r'\d+')
result = pattern.findall('There are 25 apples and 30 oranges')
print(result)  # 输出:['25', '30']

10.替换和替换操作

pattern = re.compile(r'\d+')
result = pattern.sub('X''There are 25 apples and 30 oranges')
print(result)  # 输出:'There are X apples and X oranges'

11.不区分大小写

pattern = re.compile(r'hello', re.IGNORECASE)
result = pattern.match('HeLLo World')
print(result.group())  # 输出:'HeLLo'

二、有效使用正则表达式的100个技巧

1.通用技巧

  1. 使用原始字符串(如 r'\d+')以避免意外的转义字符。
  2. 若需多次使用正则表达式模式,建议编译模式以提升性能。
    import re

    # 不编译模式(重复编译)
    for _ in range(1000):
        result = re.match(r'\d+''123')

    # 编译模式(仅编译一次)
    pattern = re.compile(r'\d+')
    for _ in range(1000):
        result = pattern.match('123')
  3. 针对多种情况测试正则表达式,确保其正确性。
    
    
    
        
    import re

    # 示例:匹配电子邮件地址
    pattern = re.compile(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b')

    # 测试用例
    test_cases = [
        "user@example.com",             # 有效的电子邮件
        "user@company.co.uk",           # 带国家代码的有效电子邮件
        "name123@sub.domain.org",       # 带子域名的有效电子邮件
        "invalid_email@no_tld",         # 无效的电子邮件(无顶级域名)
        "@missing_username.com",        # 无效的电子邮件(无用户名)
        "user@invalid_domain",          # 无效的电子邮件(域名无效)
        "name@server.c",                # 无效的电子邮件(顶级域名过短)
        "name@server.with_space.com",   # 无效的电子邮件(域名含空格)
        "user@@double_at.com",          # 无效的电子邮件(含两个@)
        "user@excessive_length_domain." + "a" * 255# 无效的电子邮件(域名过长)
    ]

    # 用每个测试用例测试模式
    for email in test_cases:
        match = pattern.match(email)
        print(f"{email}{'有效' if match else '无效'}")

2.字符类

  1. 利用字符类(如 [a-z])匹配指定范围内的任意字符。
  2. 使用否定(字符类中的 ^)匹配不在指定范围内的字符(如 [^0-9] 匹配非数字)。

3.量词

  1. 需匹配最小内容时,优先使用非贪婪量词(*?+?)。
  2. 使用贪婪量词(*+)时需谨慎,避免意外的长匹配。

4.锚点和边界

  1. 使用 ^ 和 $ 分别将模式锚定到行的开头和结尾。
  2. 利用单词边界(\b)匹配完整单词。

5.选择和分组

  1. 使用选择(|)匹配多个模式(如 cat|dog)。
  2. 需对模式的特定部分(而非整个模式)应用量词(*+{})或选择(|)时,分组非常有用。

6.字符转义

  1. 熟悉常见的字符转义(\d\w\s),分别用于匹配数字、单词字符和空白字符。
  2. 若需匹配特殊字符(如 .),需转义(如 \.)。

7.环视

  1. 使用正向前瞻((?=...))匹配后面跟有特定模式的内容。
  2. 利用负向前瞻((?!...))匹配后面不跟特定模式的内容。

8.替换

  1. 使用捕获组在替换中提取并引用匹配字符串的部分内容。
    
    
    
        
    import re

    # 示例:替换日期格式
    pattern = re.compile(r'(\d{1,2})/(\d{1,2})/(\d{4})')

    # 原始字符串
    text = "Meeting on 12/25/2022. Deadline is 3/8/2023."

    # 使用捕获组进行替换
    result = pattern.sub(r'\3-\1-\2', text)

    # 打印结果
    print(f"原始:{text}")
    print(f"修改后:{result}")
  2. 尝试使用反向引用(\1\2)在替换中引用捕获组。

9.常见模式

  1. 使用 \d+ 匹配一个或多个数字。
  2. 使用 ? 匹配可选字符(如 colou?r 匹配 color 或 colour)。
  3. 使用 \s+ 匹配空白字符。

10.不区分大小写

使用 re.IGNORECASE 标志启用不区分大小写的匹配。

11.注释

使用 (?#comment) 在正则表达式中添加注释,提高可读性。

12.验证

  1. 使用健壮的正则表达式模式验证电子邮件地址。

    import re

    def validate_email(email):
        # 电子邮件验证的正则表达式模式
        pattern = re.compile(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$')
        return bool(pattern.match(email))

    # 测试用例
    emails = [
        "user@example.com",          # 有效的电子邮件
        "user.name@company.co.uk",   # 带国家代码的有效电子邮件
        "invalid_email@no_tld",      # 无效的电子邮件(无顶级域名)
        "@missing_username.com",     # 无效的电子邮件(无用户名)
        "user@invalid_domain",       # 无效的电子邮件(域名无效)
        "user@@double_at.com",       # 无效的电子邮件(含两个@)
        "user@excessive_length_domain." + "a" * 255# 无效的电子邮件(域名过长)
    ]

    # 验证每个电子邮件并打印结果
    for email in emails:
        result = validate_email(email)
        print(f"{email}{'有效' if result else '无效'}")
  • ^[a-zA-Z0-9._%+-]+:匹配用户名部分中一个或多个允许的字符。
  • @:匹配 @ 符号。
  • [a-zA-Z0-9.-]+:匹配域名部分中一个或多个允许的字符。
  • \.:匹配顶级域名前的点(.)。
  • [a-zA-Z]{2,}$:匹配两个或多个字母的顶级域名。
  • 为电话号码创建正则表达式模式。

    import re

    def validate_phone_number(phone_number):
        # 带或不带连字符的美国电话号码的正则表达式模式
        pattern = re.compile(r'^\+?1?\s*[-.]?\s*\(?\d{3}\)?[-.]?\s*\d{3}[-.]?\s*\d{4}$')
        return bool(pattern.match(phone_number))

    # 测试用例
    phone_numbers = [
        "+1 123-456-7890",     # 带国家代码的有效电话号码
        "123.456.7890",        # 带点的有效电话号码
        "(123) 456-7890",      # 带括号的有效电话号码
        "1234567890",          # 无连字符的有效电话号码
        "987-654-3210",        # 无国家代码的有效电话号码
        "invalid_phone_number"# 无效的电话号码
    ]

    # 验证每个电话号码并打印结果
    for phone_number in phone_numbers:
        result = validate_phone_number(phone_number)
        print(f"{phone_number}{'有效' if result else '无效'}")
    • ^:断言字符串的开头。
    • \+?1?:匹配可选的 + 和可选的 1(国家代码)。
    • \s*[-.]?\s*:匹配可选的空格和可选的连字符或点。
    • \(?\d{3}\)?:匹配可选的左括号、三个数字和可选的右括号。
    • [-.]?\s*\d{3}[-.]?\s*\d{4}$:匹配可选的连字符或点、可选的空格、三个数字、可选的连字符或点、可选的空格,以及结尾的四个数字。
  • 为邮政编码创建正则表达式模式。

    
    
    
        
    import re

    def validate_zip_code(zip_code):
        # 美国邮政编码的正则表达式模式(5位或9位)
        pattern = re.compile(r'^\d{5}(?:[-\s]\d{4})?$')
        return bool(pattern.match(zip_code))

    # 测试用例
    zip_codes = [
        "12345",            # 有效的5位邮政编码
        "98765-4321",       # 带连字符的有效的9位邮政编码
        "56789 1234",       # 带空格的有效的9位邮政编码
        "invalid_zip_code"# 无效的邮政编码
    ]

    # 验证每个邮政编码并打印结果
    for zip_code in zip_codes:
        result = validate_zip_code(zip_code)
        print(f"{zip_code}{'有效' if result else '无效'}")
    • ^:断言字符串的开头。
    • \d{5}:匹配5位数字(5位邮政编码)。
    • (?:[-\s]\d{4})?:使用非捕获组使最后四位数字可选,允许带可选连字符或空格的9位邮政编码格式。
    • $:断言字符串的结尾。

    13.转义用户输入

    将用户输入纳入正则表达式时,务必转义用户输入,以防止注入攻击。

    import re

    def search_string_in_text(user_input, text):
        # 在正则表达式中使用用户输入前安全转义
        escaped_user_input = re.escape(user_input)

        # 在正则表达式模式中使用转义后的用户输入
        pattern = re.compile(f'\\b{escaped_user_input}\\b', re.IGNORECASE)

        # 在文本中搜索转义后的用户输入
        match = pattern.search(text)

        # 打印结果
        if match:
            print(f"找到:'{user_input}' 在 '{text}' 中")
        else:
            print(f"未找到:'{user_input}' 在 '{text}' 中")

    # 用用户输入和文本测试
    search_string_in_text(".*""这是一段简单的文本。")
    • re.escape(user_input)re.escape() 函数转义用户输入中的特殊字符,确保它们被视为字面字符而非正则表达式语法的一部分。
    • \\b{escaped_user_input}\\b{escaped_user_input} 被纳入正则表达式模式,前后包围 \b 单词边界以匹配确切的单词。
    • re.IGNORECASEre.IGNORECASE 标志用于执行不区分大小写的搜索。

    14.命名组

    使用命名组((?P...))提高可读性,并通过名称引用捕获的组。

    15.详细模式

    启用详细模式(re.VERBOSE 或 re.X),允许模式中包含空格和注释,提高可读性。

    16.非捕获组

    使用非捕获组 (?:...) 进行分组,而不创建捕获组。

    17.Unicode 字符

    考虑使用 \p{L} 匹配任何 Unicode 字母。

    18.转义点号

    若需匹配字面点号,使用 \.

    19.验证 URL

    创建正则表达式模式验证 URL。

    import re

    def validate_url(url):
        # 验证 URL 的正则表达式模式
        pattern = re.compile(
            r'^(https?|ftp):\/\/'# 协议(http、https、ftp)
            r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|[0-9]{1,3}\.?|[A-Z0-9-]+\.?)'# 域名
            r'(?:\/[^\s]*)?$'# 路径
            , re.IGNORECASE
        )
        return bool(pattern.match(url))

    # 测试用例
    urls = [
        "http://www.example.com",
        "https://example.com/path",
        "ftp://ftp.example.net/file.txt",
        "invalid-url",
        "ftp://invalid_domain",
        "https://example_with_underscores.com"
    ]

    # 验证每个 URL 并打印结果
    for url in urls:
        result = validate_url(url)
        print(f"{url}{'有效' if result else '无效'}")
    • ^(https?|ftp):\/\/:匹配协议(http、https 或 ftp)。
    • (?: ... | ... ):域名选项的非捕获组。
    • (?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?:匹配典型域名(example.com),带可选子域名。
    • |[0-9]{1,3}\.?:或者,匹配 IP 地址(带可选尾点)。
    • |[A-Z0-9-]+\.?:或者,匹配仅含字母数字的域名(example-with-hyphens.com),带可选尾点。
    • (?:\/[^\s]*)?$:匹配字符串末尾的路径(例如,/path/to/resource)。
    • re.IGNORECASEre.IGNORECASE 标志用于执行不区分大小写的匹配。

    20.提取信息

    使用捕获组从字符串中提取特定信息。

    import re

    def extract_email_info(email):
        # 带捕获组的正则表达式模式,用于提取电子邮件信息
        pattern = re.compile(r'^([a-zA-Z0-9._%+-]+)@([a-zA-Z0-9.-]+)\.([a-zA-Z]{2,})$')

        # 用模式匹配电子邮件
        match = pattern.match(email)

        # 使用捕获组提取信息
        if match:
            username, domain, tld = match.groups()
            print(f"电子邮件:{email}")
            print(f"用户名:{username}")
            print(f"域名:{domain}")
            print(f"顶级域名:{tld}")
        else:
            print(f"无效的电子邮件格式:{email}")

    # 测试用例
    emails = [
        "user@example.com",
        "john.doe@company.co.uk",
        "invalid_email@no_tld",
        "@missing_username.com",
        "user@invalid_domain",
        "user@@double_at.com",
        "user@excessive_length_domain." + "a" * 255
    ]

    # 从每个电子邮件提取信息并打印结果
    for email in emails:
        extract_email_info(email)
        print("-" * 30)
    • ^([a-zA-Z0-9._%+-]+):电子邮件用户名部分的捕获组。
    • @:匹配 @ 符号。
    • ([a-zA-Z0-9.-]+):电子邮件域名部分的捕获组。
    • \.:匹配顶级域名前的点(.)。
    • ([a-zA-Z]{2,})$:顶级域名的捕获组。
    • match.groups():以元组形式检索捕获的组。

    21.字符集和范围

    使用字符集和范围简洁地匹配多个字符。

    import re

    def match_date_formats(date_string):
        # 带字符集和范围的正则表达式模式,用于匹配日期格式
        pattern = re.compile(r'^\d{1,2}[/\-]\d{1,2}[/\-]\d{2,4}$')

        # 检查日期字符串是否匹配模式
        if pattern.match(date_string):
            print(f"{date_string} 是有效的日期格式。")
        else:
            print(f"{date_string} 不是有效的日期格式。")

    # 测试用例
    date_strings = [
        "12/25/2022",
        "3-8-2023",
        "invalid_date",
        "2023-12-31",
        "15/07/2021",
        "22-10-21"
    ]

    # 每个日期字符串与模式匹配并打印结果
    for date_str in date_strings:
        match_date_formats(date_str)

    ^\d{1,2}[/\-]\d{1,2}[/\-]\d{2,4}$:此正则表达式模式使用字符集和范围匹配不同的日期格式。

    • ^\d{1,2}:匹配开头的1或2位数字。
    • [/\-]:匹配斜杠(/)或连字符(-)。
    • \d{1,2}:匹配1或2位数字(月份)。
    • [/\-]:匹配另一个斜杠(/)或连字符(-)。
    • \d{2,4}$:匹配结尾的2、3或4位数字(年份)。

    22.非贪婪字符匹配

    组合 .*? 用于非贪婪匹配任何字符。

    23.匹配整个单词

    使用 \b 匹配整个单词。

    24.匹配特殊字符

    要匹配字面意义上的 +* 和 ? 等特殊字符,需要转义它们。

    25.组上的量词

    将量词应用于组以匹配重复模式(例如,(ab)+)。

    26.匹配日期

    创建正则表达式模式匹配日期格式。

    1. 模式1:MM/DD/YYYY 或 MM-DD-YYYY

      import re

      def match_date_format_1(date_string):
          pattern = re.compile(r'^(0[1-9]|1[0-2])[/\-](0[1-9]|[12][0-9]|3[01])[/\-]\d{4}$')
          if pattern.match(date_string):
              print(f"{date_string} 匹配模式。")
          else:
              print(f"{date_string} 不匹配模式。")

      # 测试用例
      dates_pattern_1 = ["12/25/2022""03-08-2023""15/07/2021""2023-12-31""invalid_date"]
      for date_str in dates_pattern_1:
          match_date_format_1(date_str)

      ^(0[1-9]|1[0-2])[/\-](0[1-9]|[12][0-9]|3[01])[/\-]\d{4}$
      匹配两位数字的月份、两位数字的日期和四位数字的年份,以斜杠(/)或连字符(-)分隔。

    2. 模式2:YYYY/MM/DD 或 YYYY-MM-DD

      
      
      
          
      import re

      def match_date_format_2(date_string):
          pattern = re.compile(r'^\d{4}[/\-](0[1-9]|1[0-2])[/\-](0[1-9]|[12][0-9]|3[01])$')
          if pattern.match(date_string):
              print(f"{date_string} 匹配模式。")
          else:
              print(f"{date_string} 不匹配模式。")

      # 测试用例
      dates_pattern_2 = ["2022/12/25""2023-03-08""2021/15/07""2023-12-31""invalid_date"]
      for date_str in dates_pattern_2:
          match_date_format_2(date_str)

      ^\d{4}[/\-](0[1-9]|1[0-2])[/\-](0[1-9]|[12][0-9]|3[01])$
      匹配四位数字的年份、两位数字的月份和两位数字的日期,以斜杠(/)或连字符(-)分隔。

    3. 模式3:DD Month YYYY

      import re

      def match_date_format_3(date_string):
          pattern = re.compile(r'^(0[1-9]|[12][0-9]|3[01])\s+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+\d{4}$', re.IGNORECASE)
          if pattern.match(date_string):
              print(f"{date_string} 匹配模式。")
          else:
              print(f"{date_string} 不匹配模式。")

      # 测试用例
      dates_pattern_3 = ["25 Dec 2022""08 March 2023""15/07/2021""31 October 2023""invalid_date"]
      for date_str in dates_pattern_3:
          match_date_format_3(date_str)

      ^(0[1-9]|[12][0-9]|3[01])\s+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+\d{4}$
      匹配两位数字的日期、三位字母的月份缩写和四位数字的年份,以空格分隔。

    27.匹配 HTML 标签

    使用正则表达式匹配或提取 HTML 标签中的内容。

    import re

    def extract_content_from_html(html):
        # 匹配 HTML 标签内内容的正则表达式模式
        pattern = re.compile(r']*>([^]*>')

        # 在 HTML 中查找所有匹配项
        matches = pattern.findall(html)

        # 打印提取的内容
        for match in matches:
            print(f"提取的内容:{match.strip()}")

    # HTML 字符串
    html_content = """

     
       

    Title


       

    This is a sample paragraph.


       
    Some italicized text.

     

    """


    # 从 HTML 标签提取内容
    extract_content_from_html(html_content)
    • ]*>:匹配开头 HTML 标签( 字符([^>]*),以及结尾 HTML 标签(>)。
    • ([^:用于匹配和提取 HTML 标签内内容的捕获组。它匹配一个或多个非 < 字符。
    • ]*>:匹配结尾 HTML 标签。
    • findall:在 HTML 字符串中查找模式的所有出现。

    28.密码验证

    设计正则表达式模式验证密码强度。

    import re

    def validate_password_strength(password):
        # 验证强密码的正则表达式模式
        pattern = re.compile(
            r'^(?=.*[a-z])'     # 至少一个小写字母
            r'(?=.*[A-Z])'      # 至少一个大写字母
            r'(?=.*\d)'         # 至少一个数字
            r'(?=.*[@$!%*?&])'# 至少一个特殊字符
            r'(?=^[^\s]{8,}$)'# 最小长度为8个字符,不允许空格
        )

        if pattern.match(password):
            print(f"{password} 是强密码。")
        else:
            print(f"{password} 不符合密码强度标准。")

    # 测试用例
    passwords = [
        "StrongPass123!",
        "WeakPassword",
        "NoSpecialCharacter1",
        "Short!23",
        "NoUpperLowerCase@1"
    ]

    # 验证每个密码并打印结果
    for password in passwords:
        validate_password_strength(password)
    • (?=.*[a-z]):至少一个小写字母。
    • (?=.*[A-Z]):至少一个大写字母。
    • (?=.*\d):至少一个数字。
    • (?=.*[@$!%*?&]):至少一个特殊字符(可自定义这个集合)。
    • (?=^[^\s]{8,}$):最小长度为8个字符,且不允许空格。

    29.替换空白字符

    用单个空格(\s+)替换连续的空白字符。

    30.提取数字

    使用 \d+ 从字符串中提取数字。

    31.提取 URL

    创建正则表达式模式从文本中提取 URL。

    1. 模式1:基本 URL 提取

      import re

      def extract_urls(text):
          # 提取 URL 的正则表达式模式
          pattern = re.compile(r'https?://\S+|www\.\S+')

          # 在文本中查找所有匹配项
          matches = pattern.findall(text)

          # 打印提取的 URL
          for match in matches:
              print(f"提取的 URL:{match}")

      # 测试用例
      text_with_urls = """
      Check out this website: https://www.example.com.
      For more information, visit http://www.another-example.org.
      """


      # 从文本中提取 URL
      extract_urls(text_with_urls)
    • https?:匹配 "http" 或 "https"。
    • ://:匹配 "://"。
    • \S+:匹配一个或多个非空白字符(域名)。
    • |:或运算符。
    • www\.\S+:匹配 "www." 后跟一个或多个非空白字符。
  • 模式2:扩展 URL 提取

    import re

    def extract_urls_extended(text):
        # 提取带可选 www 和查询参数的 URL 的正则表达式模式
        pattern = re.compile(r'https?://(?:www\.)?\S+(?:\?\S+)?')

        # 在文本中查找所有匹配项
        matches = pattern.findall(text)

        # 打印提取的 URL
        for match in matches:
            print(f"提取的 URL:{match}")

    # 测试用例
    text_with_urls_extended = """
    Check out this website: https://www.example.com/path/page?query=123.
    For more information, visit http://another-example.org.
    """


    # 从文本中提取 URL
    extract_urls_extended(text_with_urls_extended)
    • (?:www\.)?:可选 "www." 的非捕获组。
    • (?:\?\S+)?):可选查询参数(以 "?" 开头)的非捕获组。

    32.匹配 HTML 实体

    使用正则表达式匹配或替换 HTML 实体。

    import re
    from html import unescape

    def replace_html_entities(text):
        # 匹配 HTML 实体的正则表达式模式
        pattern = re.compile(r'&[a-zA-Z]+;')

        # 在文本中查找所有匹配项
        matches = pattern.findall(text)

        # 将每个 HTML 实体替换为其解码后的等效字符
        for match in matches:
            decoded_entity = unescape(match)
            text = text.replace(match, decoded_entity)

        return text

    # 测试用例
    html_text = "This is an example with HTML entities."

    # 替换文本中的 HTML 实体
    result_text = replace_html_entities(html_text)

    # 打印结果
    print("原始文本:", html_text)
    print("替换后:", result_text)

    正则表达式模式 &[a-zA-Z]+; 用于匹配常见的 HTML 实体。然后使用 html 模块中的 unescape 函数将每个 HTML 实体替换为其解码后的等效字符。

    33.匹配文件路径

    设计正则表达式模式匹配文件路径。

    1. 模式1:Unix/Linux 文件路径

      import re

      def match_unix_file_path(path):
          # 匹配 Unix/Linux 文件路径的正则表达式模式
          pattern = re.compile(r'^\/(?:[^\/]+\/)*[^\/]+$')

          if pattern.match(path):
              print(f"{path} 是有效的 Unix/Linux 文件路径。")
          else:
              print(f"{path} 不是有效的 Unix/Linux 文件路径。")

      # 测试用例
      unix_paths = [
          "/home/user/documents/file.txt",
          "/var/www/html/index.html",
          "relative/path/to/file",
          "invalid\\path\\file.txt"
      ]

      for path in unix_paths:
          match_unix_file_path(path)
    • ^:断言字符串的开头。
    • \/:匹配根目录("/")。
    • (?:[^\/]+\/)*:非捕获组,匹配零个或多个非斜杠字符后跟斜杠的序列。
    • [^\/]+$:匹配字符串末尾一个或多个非斜杠字符。
  • 模式2:Windows 文件路径

    import re

    def match_windows_file_path(path):
        # 匹配 Windows 文件路径的正则表达式模式
        pattern = re.compile(r'^[a-zA-Z]:\\(?:[^\\]+\\)*[^\\]+$')

        if pattern.match(path):
            print(f"{path} 是有效的 Windows 文件路径。")
        else:
            print(f"{path} 不是有效的 Windows 文件路径。")

    # 测试用例
    windows_paths = [
        "C:\\Users\\User\\Documents\\file.txt",
        "D:/Projects/project1/code.py",
        "\\absolute\\path\\file.txt",
        "/unix/style/path/file"
    ]

    for path in windows_paths:
        match_windows_file_path(path)
    • ^:断言字符串的开头。
    • [a-zA-Z]:\\:匹配驱动器号(例如,"C:")后跟反斜杠。
    • (?:[^\\]+\\)*:非捕获组,匹配零个或多个非反斜杠字符后跟反斜杠的序列。
    • [^\\]+$:匹配字符串末尾一个或多个非反斜杠字符。

    34.提取电子邮件地址

    创建正则表达式模式从文本中提取电子邮件地址。

    1. 模式1:基本电子邮件地址提取

      import re

      def extract_email_addresses (text):
          # 基本电子邮件地址提取的正则表达式模式
          pattern = re.compile(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b')

          # 在文本中查找所有匹配项
          matches = pattern.findall(text)

          # 打印提取的电子邮件地址
          for match in matches:
              print(f"提取的电子邮件:{match}")

      # 测试用例
      text_with_emails = """
      Contact us at support@example.com for assistance.
      Send your inquiries to info@company.org or sales@business.com.
      Invalid emails: user@invalid, @missing_username.com, email@in@valid.com
      """


      # 从文本中提取电子邮件地址
      extract_email_addresses(text_with_emails)

      \b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b

    • \b:单词边界,确保匹配整个电子邮件地址。
    • [A-Za-z0-9._%+-]+:匹配电子邮件的用户名部分。
    • @:匹配 @ 符号。
    • [A-Za-z0-9.-]+:匹配域名。
    • \.:匹配顶级域名前的点。
    • [A-Z|a-z]{2,}:匹配至少2个字符的顶级域名(TLD)。
  • 模式2:扩展电子邮件地址提取

    import re

    def extract_email_addresses_extended(text):
        # 扩展电子邮件地址提取的正则表达式模式
        pattern = re.compile(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}(?:\.[A-Z|a-z]{2,})?\b')

        # 在文本中查找所有匹配项
        matches = pattern.findall(text)

        # 打印提取的电子邮件地址
        for match in matches:
            print(f"提取的电子邮件:{match}")

    # 测试用例
    text_with_emails_extended = """
    Contact us at support@example.com for assistance.
    Send your inquiries to info@company.org or sales@business.co.uk.
    Invalid emails: user@invalid, @missing_username.com, email@in@valid.com
    """


    # 从文本中提取电子邮件地址
    extract_email_addresses_extended(text_with_emails_extended)

    ...(?:\.[A-Z|a-z]{2,})?\b

    • (?: ... )?:可选附加子域名的非捕获组。
    • \.:匹配附加子域名前的点。
    • [A-Z|a-z]{2,}:匹配至少2个字符的附加子域名。

    35.匹配 IPv4 地址

    设计正则表达式模式匹配 IPv4 地址。

    1. 模式1:基本 IPv4 地址匹配

      import re

      def match_ipv4_addresses(text):
          # 基本 IPv4 地址匹配的正则表达式模式
          pattern = re.compile(r'\b(?:\d{1,3}\.){3}\d{1,3}\b')

          # 在文本中查找所有匹配项
          matches = pattern.findall(text)

          # 打印匹配的 IPv4 地址
          for match in matches:
              print(f"匹配的 IPv4 地址: {match}")

      # 测试用例
      text_with_ipv4 = """
      Server 1: 192.168.1.1
      Server 2: 10.0.0.255
      Invalid IP: 256.256.256.256
      """


      # 在文本中匹配 IPv4 地址
      match_ipv4_addresses(text_with_ipv4)

      \b(?:\d{1,3}\.){3}\d{1,3}\b

    • \b:单词边界,确保匹配整个 IPv4 地址。
    • (?:\d{1,3}\.){3}:非捕获组,匹配三次 "1-3 位数字后跟点"。
    • \d{1,3}:匹配最后一个八位字节(1-3 位数字)。
  • 模式2:扩展 IPv4 地址匹配

    import re

    def match_ipv4_addresses_extended(text):
        # 扩展 IPv4 地址匹配的正则表达式模式
        pattern = re.compile(r'\b(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'
                           r'(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}\b')

        # 在文本中查找所有匹配项
        matches = pattern.findall(text)

        # 打印匹配的 IPv4 地址
        for match in matches:
            print(f"匹配的 IPv4 地址:{match}")

    # 测试用例
    text_with_ipv4_extended = """
    Server 1: 192.168.1.1
    Server 2: 10.0.0.255
    Invalid IP: 256.256.256.256
    """


    # 在文本中匹配 IPv4 地址
    match_ipv4_addresses_extended(text_with_ipv4_extended)

    \b(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)

    • (?: ... ){3}:非捕获组,匹配三次以下模式。
    • 25[0-5]:匹配 250 到 255 之间的数字。
    • 2[0-4][0-9]:匹配 200 到 249 之间的数字。
    • [01]?[0-9][0-9]?:匹配 0 到 199 之间的数字。

    36.转义符上的量词

    将量词直接应用于转义符(例如,\d{3} 匹配三位数字)。

    37.匹配信用卡号

    创建正则表达式模式匹配或验证信用卡号。

    1. 模式1:基本信用卡号验证

      
      
      
          
      import re

      def validate_credit_card_number_basic(card_number):
          # 基本信用卡号验证的正则表达式模式
          pattern = re.compile(r'^\d{13,19}$')

          if pattern.match(card_number):
              print(f"{card_number} 可能是有效的信用卡号。")
          else:
              print(f"{card_number} 不是有效的信用卡号。")

      # 测试用例
      credit_cards_basic = [
          "1234567890123",
          "4567-8901-2345-6789",
          "1234 5678 9012 3456",
          "invalid_card",
      ]

      for card in credit_cards_basic:
          validate_credit_card_number_basic(card)

      ^\d{13,19}$:匹配长度在13到19个字符之间的数字字符串。

    2. 模式2:带卢恩算法的信用卡号验证

      import re

      def validate_credit_card_number_luhn(card_number):
          # 带卢恩算法的信用卡号验证的正则表达式模式
          pattern = re.compile(r'^\d{13,19}$')

          ifnot pattern.match(card_number):
              print(f"{card_number} 不是有效的信用卡号。")
              return

          # 移除非数字字符
          digits = [int(digit) for digit in card_number if digit.isdigit()]

          # 应用卢恩算法
          total = sum(digits[::-2] + [sum(divmod(d * 210)) for d in digits[-2::-2]])
          if total % 10 == 0:
              print(f"{card_number} 是有效的信用卡号。")
           else:
              print(f"{card_number} 不是有效的信用卡号。")

      # 测试用例
      credit_cards_luhn = [
          "1234567890123",
          "4567-8901-2345-6789",
          "1234 5678 9012 3456",
          "invalid_card",
      ]

      for card in credit_cards_luhn:
          validate_credit_card_number_luhn(card)
    • ^\d{13,19}$:与基本模式相同,用于初始数字验证。
    • 卢恩算法用于检查信用卡号的有效性。

    38.匹配特定单词

    使用 \b 匹配较大文本中的特定单词。

    39.转义字符

    1. 使用 \ 转义特殊字符,如 ^$()[]{}.*+?|\
    2. 在非特殊字符前使用 \ 以字面匹配它。

    40.Unicode 和单词边界

    1. 使用 \b 作为单词边界,\B 作为非单词边界。
    2. 对于 Unicode 单词边界,结合 re.UNICODE 标志使用 \b

    41.匹配或排除字符

    1. 使用 . 匹配除换行符外的任何字符。
    2. 使用 [^...] 匹配不在指定集合中的任何字符。

    42.量词组合

    1. 组合量词以提高灵活性(例如,a{2,4} 匹配 'aa'、'aaa' 或 'aaaa')。
    2. 使用 {0,} 或 * 表示零次或多次出现。

    43.分组和选择

    1. 使用括号进行分组,并对序列应用量词。

      import re

      # 包含电话号码的示例文本
      text = """
      Phone Numbers:
      - (555) 123-4567
      - (123) 456-7890
      - (987) 654-3210
      """


      # 带分组和量词的正则表达式模式,用于匹配电话号码
      pattern = re.compile(r'\(\d{3}\) \d{3}-\d{4}')

      # 在文本中查找所有匹配项
      matches = pattern.findall(text)

      # 打印匹配的电话号码
      for match in matches:
          print("匹配的电话号码:", match)
    • \(:匹配左括号。
    • \d{3}:匹配恰好三位数字。
    • \):匹配右括号。
    • :匹配空格。
    • \d{3}:匹配恰好三位数字。
    • -:匹配连字符。
    • \d{4}:匹配恰好四位数字。
  • 利用 (?:...) 作为非捕获组。

  • 利用选择匹配多个可能的模式(例如,cat|dog|bird)。

  • 44.替换中的捕获组

    1. 在替换模式中使用 \1\2 等利用捕获组。
    2. 对命名捕获组使用 \g

    45.环视

    1. 使用正向后顾((?<=...))匹配前面有特定模式的内容。
    2. 应用负向后顾((?)匹配前面没有特定模式的内容。
    3. 利用正向前瞻((?=...))匹配后面有特定模式的内容。
    4. 利用负向前瞻((?!...))匹配后面没有特定模式的内容。

    46.命名捕获组

    1. 使用命名捕获组提高代码可读性。
    2. 使用 match.group('name') 访问命名捕获组。

    47.详细模式

    1. 启用详细模式(re.VERBOSE 或 re.X),支持多行模式和注释。
    2. 将复杂模式拆分为多行,提高可读性。
      import re

      # 包含电子邮件地址的示例文本
      text = """
      Email Addresses:
      - user@example.com
      - john.doe@company.org
      - contact@my-website.co.uk
      """


      # 带换行符的正则表达式模式,提高可读性
      pattern = re.compile(
          r'\b'                    # 单词边界
          r'[a-zA-Z0-9._%+-]+@'     # 用户名部分
          r'[a-zA-Z0-9.-]+\.'      # 域名部分(第一级)
          r'[A-Z|a-z]{2,}'         # 域名部分(顶级)
          r'\b'                    # 单词边界
      )

      # 在文本中查找所有匹配项
      matches = pattern.findall(text)

      # 打印匹配的电子邮件地址
      for match in matches:
          print("匹配的电子邮件地址:", match)

    48.标志和模式

    1. 利用标志,如 re.IGNORECASE 进行不区分大小写的匹配。
    2. 使用按位 OR 组合多个标志(例如,re.IGNORECASE | re.MULTILINE)。

    49.验证和提取电子邮件域名

    1. 使用正则表达式模式验证电子邮件域名。

      import re

      def validate_email_domain(email):
          # 基本电子邮件地址验证的正则表达式模式
          email_pattern = re.compile(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b')

          # 检查电子邮件地址是否匹配模式
          ifnot email_pattern.match(email):
              print(f"{email} 不是有效的电子邮件地址。")
              return

          # 从电子邮件地址提取域名
          domain_pattern = re.compile(r'@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b')
          domain_match = domain_pattern.search(email)

          if domain_match:
              domain = domain_match.group()[1:]
              print(f"{email} 的域名是 {domain}。")
          else:
              print(f"无法从 {email} 提取域名。")

      # 测试用例
      emails = [
          "user@example.com",
          "john.doe@company.org",
          "invalid-email",
      ]

      for email in emails:
          validate_email_domain(email)

      请注意,这种方法有局限性,不能保证域名的有效性。对于更可靠的解决方案,考虑使用专门的电子邮件验证库或服务。使用 DNS 查找验证域名是更可靠的方法,但需要正则表达式之外的额外步骤。

    • email_pattern 正则表达式与基本电子邮件地址验证中使用的相同。
    • domain_pattern 正则表达式用于从电子邮件地址提取域名部分。
    • @[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b:匹配 @ 符号后的域名部分。
  • 使用模式中的捕获组提取电子邮件域名。

    import re

    def extract_email_domain(email):
        # 带捕获组的正则表达式模式,用于提取电子邮件域名
        pattern = re.compile(r'\b[A-Za-z0-9._%+-]+@([A-Za-z0-9.-]+\.[A-Z|a-z]{2,})\b')

        # 用模式匹配电子邮件地址
        match = pattern.search(email)

        if match:
            domain = match.group(1)
            print(f"{email} 的域名是 {domain}。")
        else:
            print(f"无法从 {email} 提取域名。")

    # 测试用例
    emails = [
        "user@example.com",
        "john.doe@company.org",
        "invalid-email",
    ]

    for email in emails:
        extract_email_domain(email)

    \b[A-Za-z0-9._%+-]+@([A-Za-z0-9.-]+\.[A-Z|a-z]{2,})\b

    group(1) 方法用于提取第一个(也是唯一一个)捕获组捕获的内容,即电子邮件域名。

    • \b:单词边界,确保匹配整个电子邮件地址。
    • [A-Za-z0-9._%+-]+:匹配电子邮件的用户名部分。
    • @:匹配 @ 符号。
    • ([A-Za-z0-9.-]+\.[A-Z|a-z]{2,}):域名部分的捕获组。
    • \b:单词边界,确保匹配整个电子邮件地址。

    50.匹配平衡括号

    创建正则表达式匹配带平衡括号的表达式。

    import regex

    def is_balanced(expression):
        # 匹配带平衡括号的表达式的正则表达式模式
        pattern = regex.compile(r'''
            \(
                (?: [^()]+ | (?R) )*
            \)
        '''
    , regex.VERBOSE)

        return bool(pattern.fullmatch(expression))

    # 测试用例
    expressions = [
        "(a + b) * (c - d)",
        "((x + y) * z)",
        "((a + b) * (c - d)",
        "a + b) * (c - d)",
    ]

    for expr in expressions:
        if is_balanced(expr):
            print(f"表达式 '{expr}' 有平衡的括号。")
        else:
            print(f"表达式 '{expr}' 没有平衡的括号。")
    • \(:匹配左括号。
    • (?: [^()]+ | (?R) )*:非捕获组,零次或多次出现以下内容:
      • [^()]+:除括号外的任何字符序列。
      • (?R):递归匹配整个模式。
    • \):匹配右括号。

    Python 中的 regex 模块支持递归模式,允许定义引用自身的模式。在这种情况下,模式 (?R) 用于递归匹配整个模式。

    51.验证 IP 地址

    1. 设计正则表达式模式验证 IPv4 和 IPv6 地址。

      import re

      def validate_ipv4_address(ipv4):
          # IPv4 地址验证的正则表达式模式
          pattern = re.compile(
              r'^'
              r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.'
              r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.'
              r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.'
              r'(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
          )

          return bool(pattern.match(ipv4))

      # 测试用例
      ipv4_addresses = [
          "192.168.1.1",
          "10.0.0.255",
          "256.256.256.256",
          "invalid-ip",
      ]

      for ipv4 in ipv4_addresses:
          if validate_ipv4_address(ipv4):
              print(f"{ipv4} 是有效的 IPv4 地址。")
          else:
              print(f"{ipv4} 不是有效的 IPv4 地址。")
      
      
      
          
      import re

      def validate_ipv6_address(ipv6):
          # IPv6 地址验证的正则表达式模式
          pattern = re.compile(
              r'^'
              r'(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$'
          )

          return bool(pattern.match(ipv6))

      # 测试用例
      ipv6_addresses = [
          "2001:0db8:85a3:0000:0000:8a2e:0370:7334",
          "invalid-ipv6",
      ]

      for ipv6 in ipv6_addresses:
          if validate_ipv6_address(ipv6):
              print(f"{ipv6} 是有效的 IPv6 地址。")
          else:
              print(f"{ipv6} 不是有效的 IPv6 地址。")

      IPv4 地址验证:

      IPv6 地址验证:

    • (?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}:验证 IPv6 地址块。
    • ::匹配冒号分隔符。
    • ^:断言字符串的开头。
    • (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?):验证每个八位字节。
    • \.:匹配点分隔符。
    • $:断言字符串的结尾。
  • 使用该模式从文本中提取 IP 地址。

    import re

    def extract_ip_addresses(text):
        # IPv4 地址提取的正则表达式模式
        ipv4_pattern = re.compile(r'\b(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b')

        # IPv6 地址提取的正则表达式模式
        ipv6_pattern = re.compile( r'\b(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}\b')

        # 在文本中查找所有匹配项
        ipv4_matches = ipv4_pattern.findall(text)
        ipv6_matches = ipv6_pattern.findall(text)

        # 打印匹配的 IP 地址
        print("IPv4 地址:")
        for ipv4_match in ipv4_matches:
            print(ipv4_match)

        print("\nIPv6 地址:")
        for ipv6_match in ipv6_matches:
            print(ipv6_match)

    # 测试用例
    sample_text = """
    本文中的 IP 地址:
    - IPv4:192.168.1.1、10.0.0.255、256.256.256.256
    - IPv6:2001:0db8:85a3:0000:0000:8a2e:0370:7334
    """


    extract_ip_addresses(sample_text)
  • 52.匹配 Markdown 链接

    创建正则表达式模式匹配和提取 Markdown 文本中的链接。

    import re

    def extract_markdown_links(markdown_text):
        # 提取行内链接的正则表达式模式
        inline_link_pattern = re.compile(r'\[([^\]]+)\]\(([^)]+)\)')

        # 提取引用式链接的正则表达式模式
        reference_link_pattern = re.compile(r'\[([^\]]+)\]:\s*([^\s]+)')

        # 在文本中查找所有行内链接
        inline_links = inline_link_pattern.findall(markdown_text)

        # 在文本中查找所有引用式链接
        reference_links = reference_link_pattern.findall(markdown_text)

        # 打印提取的链接
        print("行内链接:")
        for title, url in  inline_links:
            print(f"标题:{title},URL:{url}")

        print("\n引用式链接:")
        for title, url in reference_links:
            print(f"标题:{title},URL:{url}")

    # 测试用例
    sample_markdown = """
    Here are some links in Markdown:

    - [Google](https://www.google.com)
    - [OpenAI](https://www.openai.com)

    Reference-style links:

    [Markdown Guide]: https://www.markdownguide.org
    [GitHub]: https://github.com
    """


    extract_markdown_links(sample_markdown)
    • inline_link_pattern 正则表达式捕获方括号([])内的文本作为链接标题,圆括号(())内的文本作为链接 URL。
    • reference_link_pattern 正则表达式捕获方括号([])内的文本作为链接标题,冒号(:)后的文本(含可选空格)作为链接 URL。

    53.匹配带引号的字符串

    设计正则表达式模式匹配文本中的带引号字符串。

    import re

    def extract_quoted_strings(text):
        # 提取单引号字符串的正则表达式模式
        single_quoted_pattern = re.compile(r"'([^']+)'")

        # 提取双引号字符串的正则表达式模式
        double_quoted_pattern = re.compile(r'"([^"]+)"')

        # 在文本中查找所有单引号字符串
        single_quoted_strings = single_quoted_pattern.findall(text)

         # 在文本中查找所有双引号字符串
        double_quoted_strings = double_quoted_pattern.findall(text)

        # 打印提取的带引号字符串
        print("单引号字符串:")
        for single_quoted in single_quoted_strings:
            print(single_quoted)

        print("\n双引号字符串:")
        for double_quoted in double_quoted_strings:
            print(double_quoted)

    # 测试用例
    sample_text = """
    Here are some quoted strings in the text:

    - Single-quoted: 'Hello, world!'
    - Double-quoted: "This is a quoted string."

    Mixed quotes: 'Single and "double" quotes.'
    """


    extract_quoted_strings(sample_text)
    • single_quoted_pattern 正则表达式捕获单引号(')内的文本作为单引号字符串的内容。
    • double_quoted_pattern 正则表达式捕获双引号(")内的文本作为双引号字符串的内容。

    54.提取 HTML 属性

    构建模式从文本中提取 HTML 标签属性。

    import re

    def extract_html_attributes(html_text):
        # 提取 HTML 标签属性的正则表达式模式
        pattern = re.compile(r']+))*\s*/?>')

        # 在文本中查找所有 HTML 标签
        matches = pattern.finditer(html_text)

        # 提取并打印标签名称和属性
        for match in matches:
            tag_name = match.group( 1)
            print(f"标签:{tag_name}")

            if match.group(2):
                attributes = match.group(2)
                attribute_pattern = re.compile(r'([a-zA-Z0-9_-]+)\s*=\s*(".*?"|\'.*?\'|[^\s>]+)')

                # 提取并打印单个属性
                for attribute_match in attribute_pattern.finditer(attributes):
                    attribute_name = attribute_match.group(1)
                    attribute_value = attribute_match.group(2)
                    print(f"  属性:{attribute_name},值:{attribute_value}")

    # 测试用例
    sample_html = """

       

    This is a paragraph


        Visit Example

    """


    extract_html_attributes(sample_html)
    • pattern 正则表达式捕获标签名称及其属性。
    • attribute_pattern 正则表达式捕获单个属性及其值。

    55.组上的量词

    将量词直接应用于组(例如,(ab)+ 匹配一个或多个 'ab' 序列)。

    56.匹配十六进制颜色

    设计模式匹配 HTML 中的十六进制颜色代码。

    import re

    def extract_hex_color_codes(html_text):
        # 匹配十六进制颜色代码的正则表达式模式
        pattern = re.compile(r'#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})\b')

        # 在文本中查找所有颜色代码
        color_codes = pattern.findall(html_text)

        # 打印匹配的颜色代码
        print("十六进制颜色代码:")
        for color_code in color_codes:
            print(color_code)

    # 测试用例
    sample_html = """

        .background-color {
            background-color: #aabbcc;
        }
        .text-color {
            color: #123;
        }

    """


    extract_hex_color_codes(sample_html)

    pattern 正则表达式匹配短格式(#abc)或长格式(#aabbcc)的十六进制颜色代码。

    • (?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})
      • (?: ... ):非捕获组。
      • [0-9a-fA-F]{3}:匹配三位十六进制数字。
      • |:选择。
      • [0-9a-fA-F]{6}:匹配六位十六进制数字。

    此模式将在给定的 HTML 文本中找到所有十六进制颜色代码。请注意,此正则表达式可能还会匹配其他类似十六进制颜色代码的模式。为了更精确地提取,你可以考虑使用专门的 HTML 解析库(如 BeautifulSoup),然后从 style 属性或内联样式中提取颜色代码。

    57.验证信用卡有效期

    创建正则表达式模式验证信用卡有效期。

    import re
    from datetime import datetime

    def validate_credit_card_expiry(expiry_date):
        # 验证 MM/YY 或 MM/YYYY 格式的信用卡有效期的正则表达式模式
        pattern = re.compile(r'^(0[1-9]|1[0-2])/(20\d{2}|[3-9]\d)$')

        # 检查日期是否匹配模式
        ifnot pattern.match(expiry_date):
            returnFalse

        # 从日期中提取月份和年份
        month, year = map(int, expiry_date.split('/'))

        # 处理年份(如果是两位数)
        if year 100:
            year += 2000

        # 检查日期是否在未来
        current_date = datetime.now()
        expiry_date = datetime(year, month, 1)

        return expiry_date > current_date

    # 测试用例
    expiry_dates = [
        "12/23",  # 有效
        "06/2024",  # 有效
        "13/25",  # 无效(月份超过12)
        "01/2000",  # 无效(已过期)
        "MM/YY",  # 无效(格式无效)
    ]

    for expiry_date in expiry_dates:
        if validate_credit_card_expiry(expiry_date):
            print(f" {expiry_date} 是有效的信用卡有效期。")
        else:
            print(f"{expiry_date} 不是有效的信用卡有效期。")

    pattern 正则表达式验证 MM/YY 或 MM/YYYY 格式的日期。

    • ^(0[1-9]|1[0-2]):匹配 MM 格式的月份(01 到 12)。
    • /:匹配分隔符。
    • (20\d{2}|[3-9]\d)$:匹配 YYYY 格式(以 20 开头)或 YY 格式(以 3-9 开头)的年份。
    • Python 代码随后检查日期是否在未来。

    请注意,虽然正则表达式可以执行基本验证,但必须基于实际日期执行额外检查以确保准确性。对于更可靠的日期处理,考虑使用 dateutil.parser 等日期解析库。

    58.匹配函数调用

    设计正则表达式模式匹配代码中的函数调用。

    import re

    def extract_function_calls(code_text):
        # 匹配函数调用的正则表达式模式
        pattern = re.compile(r'\b([a-zA-Z_]\w*)\s*\([^)]*\)')

        # 在文本中查找所有函数调用
        matches = pattern.findall(code_text)

        # 打印匹配的函数调用
        print("函数调用:")
        for match in matches:
            print(match)

    # 测试用例
    sample_code = """
    def hello_world():
        print("Hello, World!")

    result = add_numbers(5, 7) + multiply(3, 4)
    """


    extract_function_calls(sample_code)

    pattern 正则表达式捕获函数调用,包含以下组件:

    • \b:单词边界,确保匹配完整的函数名。
    • ([a-zA-Z_]\w*):捕获函数名(以字母或下划线开头,后跟字母、数字或下划线)。
    • \s*:匹配可选空格。
    • \(:匹配函数调用的左括号。
    • [^)]*:匹配除右括号外的任何字符,允许包含参数。
    • \):匹配函数调用的右括号。

    59.匹配 SQL 查询

    创建模式匹配文本中的 SQL 查询。

    import re

    def extract_sql_queries(text):
        # 匹配 SQL 查询的正则表达式模式
        pattern = re.compile(r'\b(SELECT|INSERT|UPDATE|DELETE|CREATE|ALTER|DROP|FROM|JOIN|WHERE|ORDER BY|GROUP BY|HAVING|LIMIT|AND|OR|IN|SET|VALUES|INTO|AS|ON|INNER|LEFT|RIGHT|OUTER)\b', re.IGNORECASE)

        # 在文本中查找所有 SQL 关键字
        matches = pattern.findall(text)

        # 打印匹配的 SQL 查询
        print("SQL 关键字:")
        for match in matches:
            print(match)

    # 测试用例
    sample_text = """
    SELECT * FROM employees WHERE department = 'IT';
    INSERT INTO customers (name, email) VALUES ('John Doe', 'john@example.com');
    UPDATE products SET price = 29.99 WHERE category = 'Electronics';
    """


    extract_sql_queries(sample_text)
    • pattern 正则表达式捕获常见的 SQL 关键字,如 SELECT、INSERT、UPDATE、DELETE 等。
    • \b:单词边界,确保匹配完整的关键字。
    • re.IGNORECASE:标志用于使模式不区分大小写。

    这是一个基本示例,可能无法覆盖所有 SQL 变体。对于更复杂的场景(如处理嵌套查询或注释),可能需要更复杂的解析器。对于更准确的 SQL 解析,考虑使用专门的 SQL 解析库或工具。

    60.匹配 XML 标签

    1. 设计模式匹配并提取 XML 标签之间的内容。
    import re

    def extract_xml_content(xml_text, tag_name):
        # 匹配并提取 XML 标签之间内容的正则表达式模式
        pattern = re.compile(rf'<{tag_name}[^>]*>(.*?){tag_name}>', re.DOTALL)

        # 在文本中查找所有匹配项
        matches = pattern.findall(xml_text)

        # 打印提取的内容
        print(f"<{tag_name}> 标签之间的内容:")
        for match in matches:
            print(match.strip())

    # 测试用例
    sample_xml = """

        Introduction to XML
        John Doe
       
            This is a sample book about XML.
       

    """


    extract_xml_content(sample_xml, 'title')
    extract_xml_content(sample_xml, 'content')
    • 该模式用于捕获指定 XML 标签之间的内容。
    • rf']*>(.*?)':通过 f 字符串动态插入标签名,匹配开始标签  与对应结束标签  之间的内容。
    • re.DOTALL 标志使正则表达式中的 . 能匹配包括换行符在内的所有字符。

    需注意,此示例适用于无嵌套标签的简单场景。对于复杂 XML 解析,建议使用 ElementTree 或 lxml 等专用 XML 解析库,它们能更精准地处理 XML 结构。

    1. 若 XML 的开始标签包含属性,可调整模式以适配,例如用 (\w+)\s*=\s*["']([^"']*)["'] 捕获属性名和属性值。

    2. 若 XML 包含命名空间前缀,可使用适配模式(如 (\w+:)?(\w+))同时捕获命名空间前缀和本地名称。

    61.匹配句子

    创建模式匹配文本中的完整句子。

    import re

    def extract_sentences(text):
        # 匹配英文完整句子的正则表达式模式
        pattern = re.compile(r'(?)

        # 按模式将文本拆分为句子
        sentences = re.split(pattern, text)

        # 打印提取的句子
        print("提取的句子:")
        for sentence in sentences:
            print(sentence.strip())

    # 测试用例
    sample_text = """
    This is the first sentence. It contains multiple words.
    The second sentence has more words. It also ends with a period.
    A third sentence exists as well, with a question mark at the end?
    """


    extract_sentences(sample_text)
    • 该模式通过正向后顾检测句子结尾的标点(. 或 ?)及后续空白。
    • (?:负向后顾,排除 "Mr." 等缩写。
    • (?:负向后顾,排除句尾常见缩写。
    • (?<=\.|\?):正向后顾,匹配句号或问号后跟空白的情况。

    需注意,此示例无法覆盖所有复杂文本场景。对于高级句子提取,建议使用 spaCy 或 NLTK 等自然语言处理库,它们专为处理语言结构设计。

    62.提取 HTML 注释

    设计模式提取 HTML 注释内的内容。

    import re

    def extract_html_comments(html_text):
        # 匹配并提取 HTML 注释内内容的正则表达式模式
        pattern = re.compile(r'', re.DOTALL)

        # 在文本中查找所有匹配项
        matches = pattern.findall(html_text)

        # 打印提取的内容
        print("HTML 注释内的内容:")
        for match in matches:
            print(match.strip())

    # 测试用例
    sample_html = """
        HTML Comments Example
       
       

    This is a paragraph.


       
       

           

    More content


       

    """


    extract_html_comments(sample_html)
    • pattern 正则表达式使用非贪婪匹配 (.*?) 捕获  之间的内容。
    • re.DOTALL:标志使正则表达式中的点(.)匹配包括换行符在内的所有字符。

    需要注意的是,虽然此示例在简单场景下可行,但使用正则表达式解析 HTML 注释可能无法覆盖所有边缘情况。对于更可靠的 HTML 解析,建议使用 Python 中的 BeautifulSoup 或 lxml 等专用 HTML 解析库,这些库专为处理 HTML 结构的复杂性而设计,能提供更可靠的 HTML 文档解析方案。

    63.匹配浮点数

    创建正则表达式模式匹配浮点数。

    import re

    def extract_float_numbers(text):
        # 匹配浮点数的正则表达式模式
        pattern = re.compile(r'-?\b(?:\d+\.\d*|\.\d+|\d+)(?:[eE][-+]?\d+)?\b')

        # 在文本中查找所有匹配项
        matches = pattern.findall(text)

        # 打印提取的浮点数
        print( "提取的浮点数:")
        for match in matches:
            print(match)

    # 测试用例
    sample_text = """
    文本中的数字:3.14、-0.5、123.456、.789、1.2e3、-4.56E-7
    非数字:abc、1.2.3、1e、1E2.5
    """


    extract_float_numbers(sample_text)

    pattern 正则表达式捕获多种格式的浮点数,各部分含义如下:

    • -?:可选的负号,用于匹配负数。
    • \b:单词边界,确保匹配完整的数字。
    • (?:\d+\.\d*|\.\d+|\d+):用于匹配三种情况的分组:
      • \d+\.\d*:带整数部分且小数部分可选的十进制数。
      • \.\d+:以小数点开头的十进制数。
      • \d+:无小数点的整数部分。
    • (?:[eE][-+]?\d+)?:可选的指数部分,形式为 e 或 E 后跟可选符号及数字。

    64.验证 MAC 地址

    设计正则表达式模式验证 MAC 地址。

    import re

    def validate_mac_address(mac_address):
        # 验证 MAC 地址的正则表达式模式
        pattern = re.compile(r'^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$')

         # 检查 MAC 地址是否匹配模式
        return bool(pattern.match(mac_address))

    # 测试用例
    mac_addresses = [
        "00:1a:2b:3c:4d:5e",
        "01-23-45-67-89-ab",
        "a1:b2:c3:d4:e5:f6",
        "invalid_mac",
    ]

    for mac_address in mac_addresses:
        if validate_mac_address(mac_address):
            print(f"{mac_address} 是有效的 MAC 地址。")
        else:
            print(f"{mac_address} 不是有效的 MAC 地址。")
    • pattern 正则表达式验证格式为 XX:XX:XX:XX:XX:XX 或 XX-XX-XX-XX-XX-XX 的 MAC 地址,其中 X 为十六进制数字(0-9、A-F、a-f)。
    • ^:匹配字符串的开头。
    • ([0-9A-Fa-f]{2}[:-]){5}:匹配五组两位十六进制数字后跟冒号或连字符的组合。
    • ([0-9A-Fa-f]{2}):匹配最后一组两位十六进制数字。
    • $:匹配字符串的结尾。

    此模式确保 MAC 地址由六组两位十六进制数字组成,各组之间用冒号或连字符分隔。可根据特定的 MAC 地址要求或格式变体进行调整。

    65.验证 URL

    使用正则表达式模式验证带可选协议的 URL。

    import re

    def validate_url(url):
        # 验证带可选协议的 URL 的正则表达式模式
        pattern = re.compile(r'^(?:(?:https?|ftp):\/\/)?[^\s\/$.?#].[^\s]*$')

        # 检查 URL 是否匹配模式
        return bool(pattern.match(url))

    # 测试用例
    urls = [
        "http://www.example.com",
        "https://example.com/path/to/page",
        "ftp://ftp.example.net",
        "www.example.org",
        "invalid url",
    ]

    for url in urls:
        if validate_url(url):
            print(f"{url} 是有效的 URL。")
        else:
            print(f"{url} 不是有效的 URL。")

    pattern 正则表达式验证带可选协议的 URL,各部分含义如下:

    • ^(?:(?:https?|ftp):\/\/)?:可选的非捕获组,用于匹配协议(http、https 或 ftp)及后跟的 "://"。
    • [^\s\/$.?#].[^\s]*$:匹配 URL 的其余部分,排除空白字符和某些特殊字符。

    66.匹配社会安全号码

    设计模式匹配并提取社会安全号码。

    import re

    def  extract_social_security_numbers(text):
        # 匹配并提取社会安全号码的正则表达式模式
        pattern = re.compile(r'\b(\d{3}-\d{2}-\d{4})\b')

        # 在文本中查找所有匹配项
        matches = pattern.findall(text)

        # 打印提取的社会安全号码
        print("提取的社会安全号码:")
        for match in matches:
            print(match)

    # 测试用例
    sample_text = """
    文本中的社会安全号码:123-45-6789、987-65-4321
    非社会安全号码:123-456-789、123-45-67890
    """


    extract_social_security_numbers(sample_text)
    • pattern 正则表达式捕获格式为 XXX-XX-XXXX 的社会安全号码,其中 X 为数字。
    • \b:单词边界,确保匹配完整的社会安全号码。

    67.提取哈希标签

    创建模式从文本中提取哈希标签。

    import re

    def extract_hashtags(text):
        # 匹配并提取哈希标签的正则表达式模式
        pattern = re.compile(r'\#\w+')

        # 在文本中查找所有匹配项
        matches = pattern.findall(text)

        # 打印提取的哈希标签
        print("提取的哈希标签:")
        for match in matches:
            print(match)

    # 测试用例
    sample_text = """
    这是一条带 #sample 文本和 #hashtags 的内容。
    #DataScience 和 #MachineLearning 是有趣的话题。
    这里没有哈希标签。
    """


    extract_hashtags(sample_text)
    • pattern 正则表达式捕获以 '#' 符号开头,后跟一个或多个单词字符(\w+)的哈希标签。
    • \#:匹配 '#' 符号。
    • \w+:匹配一个或多个单词字符(字母、数字或下划线)。

    68.匹配 Python 文档字符串

    创建模式匹配代码中的 Python 文档字符串。

    import re

    def extract_python_docstrings(code):
        # 匹配 Python 文档字符串的正则表达式模式
        pattern = re.compile(r'(\'\'\'|\"\"\".*?\'\'\'|\"\"\".*?\"\"\")', re.DOTALL)

        # 在代码中查找所有匹配项
        matches = pattern.findall(code)

        # 打印提取的 Python 文档字符串
        print("提取的 Python 文档字符串:")
        for match in matches:
            print(match)

    # 测试用例
    sample_code = """
    def example_function():
        '''
        这是示例函数的文档字符串。
        它可以跨多行。
        '''
        pass

    class ExampleClass:
        \"\"\"
        ExampleClass 的文档字符串。
        它提供了关于该类的信息。
        \"\"\"
        def __init__(self):
            pass
    """


    extract_python_docstrings(sample_code)
    • pattern 正则表达式捕获用三重单引号或三重双引号(''' 或 """)括起来的文档字符串。re.DOTALL 标志用于使正则表达式中的点(.)匹配包括换行符在内的所有字符。

    此正则表达式模式提供了一种捕获 Python 文档字符串的基本方法,但需要注意的是,Python 文档字符串的格式多样(例如,可能带或不带三重引号、使用单引号或双引号等)。对于更可靠的解决方案,可考虑使用 ast 等专用的 Python 解析器或库从代码中提取文档字符串。

    69.匹配 Markdown 标题

    设计正则表达式模式匹配 Markdown 标题。

    import re

    def extract_markdown_headings(markdown_text):
        # 匹配不同级别 Markdown 标题的正则表达式模式
        heading_patterns = [
            re.compile(r'^#\s(.+)$', re.MULTILINE),      # 一级标题
            re.compile(r'^##\s(.+)$', re.MULTILINE),     # 二级标题
            re.compile(r'^###\s(.+)$', re.MULTILINE),    # 三级标题
            re.compile(r'^####\s(.+)$', re.MULTILINE),   # 四级标题
            re.compile(r'^#####\s(.+)$', re.MULTILINE),  # 五级标题
            re.compile(r'^######\s(.+)$', re.MULTILINE)  # 六级标题
        ]

        # 在文本中查找每个级别标题的所有匹配项
        for i, pattern in enumerate(heading_patterns, start=1):
            matches = pattern.findall(markdown_text)
            print(f"提取的  {i} 级标题:")
            for match in matches:
                print(match)

    # 测试用例
    sample_markdown = """
    # 一级标题

    ## 二级标题

    ### 三级标题

    #### 四级标题

    ##### 五级标题

    ###### 六级标题

    非标题:
    - 项目符号
    """


    extract_markdown_headings(sample_markdown)
    • 这些正则表达式模式使用 ^ 匹配行的开头,通过相应数量的 # 符号加空格来识别不同级别的标题。
    • (.+)$ 捕获标题的内容。

    70.验证十六进制颜色代码

    使用正则表达式模式验证十六进制颜色代码。

    import re

    def validate_hex_color_code(color_code):
        # 验证十六进制颜色代码的正则表达式模式
        pattern = re.compile(r'^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$')

        # 检查颜色代码是否匹配模式
        return bool(pattern.match(color_code))

    # 测试用例
    color_codes = [
        "#123456",
        "#abc",
        "#fff",
        "#invalid",
    ]

    for color_code in color_codes:
        if validate_hex_color_code(color_code):
            print(f"{color_code} 是有效的十六进制颜色代码。")
        else:
            print(f"{color_code} 不是有效的十六进制颜色代码。")
    • pattern 正则表达式验证形式为 #RRGGBB 或 #RGB 的十六进制颜色代码,其中 R、G、B 为十六进制数字。
    • ^#:匹配字符串的开头和 '#' 符号。
    • ([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}):匹配六位或三位十六进制数字。
    • $:匹配字符串的结尾。

    71.匹配时间格式

    创建模式匹配 HH:MM:SS、HH:MM 格式的时间以及带 AM/PM 的变体形式。

    import re

    def extract_times(text):
        # 匹配不同格式时间的正则表达式模式
        time_patterns = [
            re.compile(r'\b([01]?[0-9]|2[0-3]):([0-5][0-9])(?::([0-5][0-9]))?\b'),  # HH:MM:SS 或 HH:MM
            re.compile(r'\b([01]?[0-9]|2[0-3]):([0-5][0-9])\s*([AaPp][Mm])?\b')      # HH:MM AM/PM
        ]

        # 在文本中查找每种时间模式的所有匹配项
        for i, pattern in enumerate(time_patterns, start=1):
            matches = pattern.findall(text)
            print(f"提取的时间(格式 {i}):")
            for match in matches:
                print(":".join(filter(None, match)))

    # 测试用例
    sample_text = """
    文本中的时间:12:34、23:45:56、9:15 AM、6:30 PM、18:45
    非时间:25:67、3:72、10:00 XYZ
    """


    extract_times(sample_text)

    第一种模式匹配 HH:MM:SS 或 HH:MM 格式的时间:

    • \b:单词边界,确保匹配完整的时间。
    • ([01]?[0-9]|2[0-3]):匹配小时(00 到 23)。
    • ([0-5][0-9]):匹配分钟(00 到 59)。
    • (?::([0-5][0-9]))?:可选地匹配以 :SS 形式表示的秒。

    第二种模式匹配 HH:MM AM/PM 格式的时间:

    • ([01]?[0-9]|2[0-3]):匹配小时(00 到 23)。
    • ([0-5][0-9]):匹配分钟(00 到 59)。
    • \s*([AaPp][Mm])?:可选地匹配 AM 或 PM。

    72.匹配嵌套括号

    设计模式匹配带指定深度嵌套括号的表达式。

    import re

    def extract_nested_brackets(text, depth):
         # 匹配带指定深度嵌套括号的表达式的正则表达式模式
        pattern = re.compile(rf'\((?:[^()]*|\((?:[^()]*|\((?:[^()]*|\((?:[^()]*|\([^()]*\))*\))*\))*\)){{{depth}}}\)')

        # 在文本中查找所有匹配项
        matches = pattern.findall(text)

        # 打印提取的带嵌套括号的表达式
        print("提取的带嵌套括号的表达式:")
        for match in matches:
            print(match)

    # 测试用例
    sample_text = """
    带嵌套括号的表达式:(a + (b * c) - d)
    另一个表达式:((x + y) / z) * (m - n)
    过深的表达式:(((p + q) - r) * s) / t
    """


    # 指定要匹配的嵌套括号深度
    nested_depth = 2

    extract_nested_brackets(sample_text, nested_depth)
    • pattern 正则表达式尝试匹配嵌套括号深度不超过指定值的表达式。
    • \( ... \):匹配一对括号。
    • (?: ... ):用于分组但不捕获的非捕获组。
    • [^()]*:匹配零个或多个除 '(' 和 ')' 之外的字符。
    • \((?:[^()]*|\((?:[^()]*|\((?:[^()]*|\((?:[^()]*|\([^()]*\))*\))*\))*\)):匹配嵌套深度不超过指定值的括号。

    需要注意的是,正则表达式并非解析括号等嵌套结构的最佳工具,尤其是当深度不固定时。对于更复杂的场景,可能需要使用解析器或更高级的方法。

    Python社区是高质量的Python/Django开发社区
    本文地址:http://www.python88.com/topic/185620