python . 模式匹配与正则表达式

本文介绍了Python中正则表达式的使用方法,包括创建正则表达式对象、匹配字符串、常用表达式等,并通过实例展示了如何简洁地进行电话号码验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    在周五晚上,学习了一波 python 的 正则表达式的使用,下面是我的一些总结:

一、正则表达式的优势

    如果我们没有使用正则表达式,如果我们想要在某个文本中查找某个字符串,例如"394-123-2445" 这类的电话号码,我们需要如下代码:

def isPhoneNumber(text):
    if len(text) != 12:
        return False
    for i in range(0, 3):
        if not text[i].isdecimal():
            return False
    if text[3] != '-':
        return False
    for i in range(4, 7):
        if not text[i].isdecimal():
            return False
    if text[7] != '-':
        return False
    for i in range(8, 12):
        if not text[i].isdecimal():
            return False
return True

而使用正则表达式:

phoneRegex = re.compile(r'\d{3}-\d{3}-\d{4}')
mo = phoneRegex.search("myhone is 234-456-12345")

相比之下,正则表达式的使用则非常的简洁。

二、python 的正则表达式的使用

    (1)创建正则表达式对象

            regex = re.compile('\d\d\d'), 使用 re.compilte()编译一个正则表达式字符串。

    (2)匹配 Regex 对象

            mo = regex.search("my num : 123"), 把要查找的文本字符串传入 search() 返回,返回一个 Match 对象。

    (3)返回匹配到的字符串

            str = mo.group()。调用  Math 对象的 group() 对象返回匹配到的字符串

三、正则表达式的书写

     (1) 精确匹配某个字符

        str = 'abcd', 这种字符串会精确的匹配 abcd 字符串

   (2)匹配任意字符

        使用 '.' 符号来任意的一个字符

    (3)是否匹配某个字符

        使用 '?' 可以保证某个字符可以出现或者不出现。比如 str = 'a?' ,a 字符可以有或者没有

    (4)匹配零次或者多次

        使用 * 号,可以匹配出现零次或多次

    (5)匹配一次或者多次

         使用 + 号,可以匹配出现一次或多次

     (6)可以指定匹配多少次

        使用花括号可以指定匹配多少次,比如 regex = re.compile(r'a{2,4}'), 可以匹配 a 出现 2次到4次的字符串


四、python 内置的表示某类字符的表达式

      \d                0-9 的任何数字

      \D                除了 0-9 的数字以外的任何字符

      \w                任何字母、数字或下划线字符

      \W                除字母、数字和下划线以外的任何字符

      \s                空格、制表符或换行符

      \S                除空格、制表符和换行符以外的任何字符


五、re 的一些常量

    查看 re.compile("\d\d", flag=0) flag 的一些常量值如下

    re.I 或者 re.IGNORECASE 

        执行不区分大小写的匹配,表达式[A-Z] 将匹配小写字母

    re.M 或者 re.MULTILINE

        指定时,模式字符'^'匹配字符串的开头和每行的开头(紧跟在每个换行符后面); 并且模式字符'$'匹配字符串的末尾和每行末尾(紧接在每个换行符之前)。默认情况下,'^' 只匹配字符串的开始位置,并且'$'匹配字符串的末尾和匹配字符串末尾的换行符(如果有)。对应于内联标志(?m)

    re.X 或者 re.VERBOSE

        该标志允许您编写正则表达式,通过允许您在视觉上分离模式的逻辑部分并添加注释,该正则表达式看起来更好,并且更易读。在该模式内的空白被忽略,当在字符类,或当由反斜杠之后除,或令牌内的类似*?(?:(?P<...>当一行包含一个#不在字符类中并且没有非转义反斜杠#的行时,最左边的所有字符 都将被忽略。

    re.S 或者 re.DOTALL

    使'.'特殊字符匹配任何字符,包括换行符; 没有这个标志,'.'将会匹配换行符之外任何内容对应于内联标志(?s)

六、符号表达式的总结:

  • ?匹配零次或一次前面的分组。

  • *匹配零次或多次前面的分组。

  • +匹配一次或多次前面的分组。

  • {n}匹配 次前面的分组。

  • {n,}匹配 次或更多前面的分组。

  • {,m}匹配零次到 次前面的分组。

  • {n,m}匹配至少 次、至多 次前面的分组。

  • {n,m}?*?+?对前面的分组进行非贪心匹配。

  • ^spam 意味着字符串必须以 spam 开始。

  • spam$意味着字符串必须以 spam 结束。

  • .匹配所有字符,换行符除外。

  • \d\w \s 分别匹配数字、单词和空格。

  •  \D\W \S 分别匹配出数字、单词和空格外的所有字符。

  •  [abc]匹配方括号内的任意字符(诸如 a或 c)。

  • [^abc]匹配不在方括号内的任意字符。


<think>嗯,用户问的是如何使用Python的json.loads结合正则表达式来查询数据。首先,我需要确认用户的需求。他们可能已经解析了JSON数据,但想用正则表达式来查找特定模式的数据,比如某个键或值。 首先,我需要明确json.loads的作用,它把JSON字符串转成Python的数据结构,比如字典或列表。之后的问题是如何在这些结构中用正则表达式搜索。用户可能不熟悉遍历数据结构的方法,或者希望更高效地查找匹配项。 接下来,用户可能遇到的问题包括如何递归遍历嵌套的JSON结构,以及如何应用正则表达式来匹配键或值。比如,他们可能想找到所有符合某个模式的键,或者值中的特定字符串。 然后,我需要考虑可能的解决方案。比如,编写一个递归函数来遍历字典和列表,检查每个键和值是否匹配正则表达式。同时,需要处理不同的数据类型,避免在非字符串类型上应用正则匹配导致的错误。 还要提醒用户注意转义字符的问题,比如JSON中的反斜杠在Python字符串中的处理,以及正则表达式中的特殊字符需要正确转义。此外,性能问题也很重要,如果数据很大,递归遍历可能会比较慢,可能需要优化或使用其他库。 用户可能没有考虑到JSON结构和正则表达式的复杂性,比如嵌套层级很深或者正则表达式不够精确导致匹配过多内容。需要给出示例代码,说明如何处理这些情况,并提供验证正则表达式的工具,帮助用户调试。 最后,总结关键点,确保用户理解步骤和注意事项,比如优先使用结构查询、转义处理、性能考量等。可能还需要比较其他方法,如jmespath,让用户有更多选择。</think>在Python中,`json.loads` 用于将JSON字符串转换为Python数据结构(如字典/列表)。**若要通过正则表达式查询其中的数据**,需结合递归遍历和正则匹配。以下是分步实现方法: --- ### 一、核心思路 1. **结构化数据优先**:先通过 `json.loads` 将JSON转为Python对象 2. **递归遍历**:深度遍历字典/列表结构 3. **正则匹配**:对键(key)或值(value)进行模式匹配 --- ### 二、具体实现代码 ```python import re import json def find_by_regex(data, pattern, search_keys=True, search_values=True): results = [] regex = re.compile(pattern) def _search(obj): if isinstance(obj, dict): for k, v in obj.items(): if search_keys and regex.search(str(k)): results.append({"key": k, "value": v, "path": "dict_key"}) if search_values: _search(v) _search(v) elif isinstance(obj, list): for idx, item in enumerate(obj): if search_values and regex.search(str(item)): results.append({"value": item, "path": f"list[{idx}]"}) _search(item) _search(data) return results # 示例用法 json_str = '{"user": {"name": "Alice_123", "contacts": ["alice@test.com", "2023-08-15"]}}' data = json.loads(json_str) # 查找包含数字的键或值 results = find_by_regex(data, r'\d+') print(results) ``` --- ### 三、关键参数说明 | 参数 | 作用 | |-----------------|----------------------------------------------------------------------| | `pattern` | 正则表达式模式(如 `r'\d+'` 匹配数字) | | `search_keys` | 是否在字典键(key)中搜索 | | `search_values` | 是否在值(value)中搜索(支持字符串/数字/嵌套结构) | --- ### 四、典型应用场景 #### 1. 匹配邮箱地址 ```python find_by_regex(data, r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b') ``` #### 2. 查找日期格式 ```python find_by_regex(data, r'\d{4}-\d{2}-\d{2}') ``` #### 3. 定位特定前缀的键 ```python find_by_regex(data, r'^user_', search_values=False) ``` --- ### 五、注意事项 1. **类型处理**:自动将非字符串类型转为 `str` 进行匹配 2. **路径追踪**:结果中包含 `path` 字段显示数据位置 3. **性能优化**:对于大型JSON数据,建议限制搜索深度或使用生成器 4. **转义处理**:JSON中的特殊字符需正确处理 ```python # 匹配包含反斜杠的内容 find_by_regex(data, r'\\w+') ``` --- ### 六、替代方案推荐 对于复杂JSON查询,可结合以下工具: 1. **jmespath**(结构化查询): ```python import jmespath jmespath.search("users[?contains(name, '123')]", data) ``` 2. **jsonpath-ng**(XPath风格查询): ```python from jsonpath_ng import parse parse('$..[?(@ =~ /\d+/)]').find(data) ``` --- ### 附:正则表达式验证工具 - 在线调试:https://regex101.com/ - VSCode插件:**Regex Previewer** - Python内置:`re.debug()`(需Python 3.11+) > **提示**:对于简单查询优先使用 `jmespath`,正则表达式更适合处理非结构化文本匹配。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值