Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python re groupdict:是否可以指定值类型?_Python_Regex - Fatal编程技术网

Python re groupdict:是否可以指定值类型?

Python re groupdict:是否可以指定值类型?,python,regex,Python,Regex,我用下面的正则表达式将轮胎规格分解为需要作为dict返回的子元素。它的数字元素需要作为int返回 以下是一个输入示例: tyre_specs = '255/45W17' 所需输出: tyre_details = {'width': 255, 'profile': 45, 'rating': 'W', 'rim': 17} 我使用一个名为capture的正则表达式模式捕获每个元素,该模式匹配所需的输出dict键。然后我使用groupdict生成输出dict。但是,所有的值都是字符串。所以我需要

我用下面的正则表达式将轮胎规格分解为需要作为dict返回的子元素。它的数字元素需要作为int返回

以下是一个输入示例:

tyre_specs = '255/45W17'
所需输出:

tyre_details = {'width': 255, 'profile': 45, 'rating': 'W', 'rim': 17}
我使用一个名为capture的正则表达式模式捕获每个元素,该模式匹配所需的输出dict键。然后我使用groupdict生成输出dict。但是,所有的值都是字符串。所以我需要进一步处理相关的值,将它们转换为int

我的函数(见下文)起作用。然而,我想知道是否有更好的方法来做到这一点。例如,是否有一种方法可以强制执行某些特定匹配组的类型

如果不是,这种方法是“pythonic”的吗

这是我的功能

import re

def tyre_details(tyre_size):
    pattern = r'(?P<width>\d{3})\/(?P<profile>\d{2})(?P<rating>[A-Z]{1,2})(?P<rim>\d{2})'
    try:
        details = re.match(pattern, tyre_size).groupdict()
    except AttributeError:
        raise ValueError('Input does not conform to the usual tyre size nomenclature "Width/ProfileRatingRim"')

    int_keys = set('width profile rim'.split())
    for key in int_keys:
        details[key] = int(details[key])
    return details
重新导入
def轮胎详细信息(轮胎尺寸):
模式=r'(?P\d{3})\/(?P\d{2})(?P[A-Z]{1,2})(?P\d{2})'
尝试:
详细信息=重新匹配(模式、轮胎尺寸).groupdict()
除属性错误外:
raise VALUE ERROR('输入不符合常用的轮胎尺寸术语“宽度/轮廓轮辋”)
int_keys=set('width profile rim'.split())
对于输入/输出键:
详细信息[key]=int(详细信息[key])
返回详细信息
编辑:

  • 添加了输入字符串不匹配时的处理异常。我认为这是一个值错误
  • 将要强制转换的键定义为集合而不是列表
  • 删除了多余的try/except子句

  • 我会先检查正则表达式是否匹配。如果有,则可以将
    match.groups()
    直接解引用到变量中,并用于构建最终的dictionary对象:

    import re
    
    def tyre_details(tyre_size):
        pattern  = r'(\d{3})/(\d{2})([A-Z]{1,2})(\d{2})'
        m = re.match(pattern, tyre_size)
        details = {}
        if m:
            width, profile, rating, rim = m.groups()
            details = {"width": int(width), "profile": int(profile), "rating": rating, "rim": int(rim)}
        return details
    
    tyre_specs = '255/45W17'
    print( tyre_details(tyre_specs) )
    # => {'width': 255, 'profile': 45, 'rating': 'W', 'rim': 17}
    

    使用这种方法不需要命名组,并且在将
    str
    强制转换为
    int
    时,不需要任何
    尝试/除了
    或其他检查,因为所讨论的组只匹配数字,请参见
    (\d{3})
    (\d{2})

    如果需要完整字符串匹配,请将
    re.match
    替换为
    re.fullmatch
    ,如果匹配可以出现在字符串中的任何位置,请使用
    re.search


    注意
    /
    不是任何特殊的regex元字符,不要在模式中转义它。

    regex只处理字符串/字节数据,您应该自己显式地将其转换为数字类型。感谢Wiktor,这是我在阅读文档时的想法。我想检查我是否遗漏了一些内容。@alfajet,1)需要检查错误匹配2)
    int\u key
    最好定义为sequence@RomanPerekhrest:谢谢你的推荐。我已经实现了它们。您不需要任何
    isdigit
    检查,因为您的组模式是
    \d{x,y}
    ,只匹配数字。除了这些情况,你不需要任何尝试。如果您担心输入中可能有任何印地语数字,请将
    \d
    替换为
    [0-9]
    。或者使用
    re.A
    /
    re.ASCII
    标志编译模式。感谢Wiktor提供了这个伟大的答案。我尝试使用groupdict,因为它似乎符合我的要求,但之后我需要进一步处理它。你的代码肯定更容易阅读。关于转义
    /
    ,这是我从
    sed“s/find/replace”
    那里得到的一个老习惯,那里需要转义
    /
    。@alfajet-Hm,我使用
    s,find,replace,
    s | find | replace |
    ,不必转义
    //code>:)