使用正则表达式和Python选择具有特殊字符的元素

使用正则表达式和Python选择具有特殊字符的元素,python,regex,Python,Regex,从字符串列表('16','160','1,2','100,11','1','16:','16:00')中,我只想保留 两位数字之间有逗号(例如1,2或100,11) 或者有两个数字(不带逗号),后面不跟“:”(即后面不跟任何东西:例如16,或者后面跟任何东西,但不跟“:”:例如160) 我在Python中使用regex尝试了以下代码: import re string = ['16','160','1,2','100,11','1','16:','16:00'] pattern_rate = r

从字符串列表('16','160','1,2','100,11','1','16:','16:00')中,我只想保留

  • 两位数字之间有逗号(例如1,2或100,11)
  • 或者有两个数字(不带逗号),后面不跟“:”(即后面不跟任何东西:例如16,或者后面跟任何东西,但不跟“:”:例如160)
  • 我在Python中使用regex尝试了以下代码:

    import re
    string = ['16','160','1,2','100,11','1','16:','16:00']
    pattern_rate = re.compile(r'(?:[\d],[\d]|[\d][\d][^:]*)')
    rate = list(filter(pattern_rate.search,string))
    print(rate)
    
    打印:

    ['16','160','1,2','100,11','16:','16:00']


    为了正确起见,脚本应该保留前三项并拒绝其余项,但我的脚本拒绝最后两项失败。我猜我使用了错误的“[^:]”符号。

    我建议深入了解一下正则表达式指南

    100不是一个数字,将与
    \d
    不匹配。如果您不打算否定或以其他方式转换组,则也不需要将组
    […]
    包含一个元素

    第一个查询可以用
    (?:\d+,\d+
    表示。它是一个非捕获组,检测长度大于等于1的逗号分隔数字

    第二个查询将在任意(*)数量的not冒号后显示任何匹配三个连续数字的内容

    您需要使用类似于
    (?:\d{2,}(?!:)
    的东西。这是一个非捕获组,匹配长度大于等于2的数字,后面不跟冒号<代码>指定负前瞻

    在python代码中,您需要使用
    pattern\u rate.match
    而不是
    pattern\u rate.find
    ,因为后者将返回部分匹配,而前者仅返回完全匹配

    pattern_rate = re.compile(r'(?:\d+,\d+)|(?:\d{2,}(?!:))')
    rate = list(filter(pattern_rate.match, string))
    

    我建议您更深入地阅读regex指南

    100不是一个数字,将与
    \d
    不匹配。如果您不打算否定或以其他方式转换组,则也不需要将组
    […]
    包含一个元素

    第一个查询可以用
    (?:\d+,\d+
    表示。它是一个非捕获组,检测长度大于等于1的逗号分隔数字

    第二个查询将在任意(*)数量的not冒号后显示任何匹配三个连续数字的内容

    您需要使用类似于
    (?:\d{2,}(?!:)
    的东西。这是一个非捕获组,匹配长度大于等于2的数字,后面不跟冒号<代码>指定负前瞻

    在python代码中,您需要使用
    pattern\u rate.match
    而不是
    pattern\u rate.find
    ,因为后者将返回部分匹配,而前者仅返回完全匹配

    pattern_rate = re.compile(r'(?:\d+,\d+)|(?:\d{2,}(?!:))')
    rate = list(filter(pattern_rate.match, string))
    

    不确定您是否需要正则表达式:

    string = ['16','160','1,2','100,11','1','16:','16:00']
    
    keep = []
    
    for elem in string:
        if ("," in elem and len(elem) == 3) or ( ":" not in elem and "," not in elem and len(elem) >= 2):
            keep.append(elem)
    
    print (keep)
    
    输出:

    ['16', '160', '1,2']
    

    虽然没有那么优雅,但往往比使用正则表达式更快。

    不确定您是否需要正则表达式:

    string = ['16','160','1,2','100,11','1','16:','16:00']
    
    keep = []
    
    for elem in string:
        if ("," in elem and len(elem) == 3) or ( ":" not in elem and "," not in elem and len(elem) >= 2):
            keep.append(elem)
    
    print (keep)
    
    输出:

    ['16', '160', '1,2']
    
    虽然没有那么优雅,但它往往比使用正则表达式更快

    为了正确起见,脚本应该保留前三项并拒绝 其余的,

    您可以匹配两个或多个数字,也可以在两个数字之间使用逗号进行匹配

    由于列表仅包含数字,因此可以使用在字符串开头开始匹配,而不是在字符串开头开始匹配

    解释

    • (?:
      非捕获组
      • \d{2,}
        匹配2个或更多数字
      • |
      • \d\d
        将两个数字之间用逗号匹配
    • 关闭非捕获组
    • \Z
      字符串结尾
    |

    输出

    ['16', '160', '1,2']
    
    为了正确起见,脚本应该保留前三项并拒绝 其余的,

    您可以匹配两个或多个数字,也可以在两个数字之间使用逗号进行匹配

    由于列表仅包含数字,因此可以使用在字符串开头开始匹配,而不是在字符串开头开始匹配

    解释

    • (?:
      非捕获组
      • \d{2,}
        匹配2个或更多数字
      • |
      • \d\d
        将两个数字之间用逗号匹配
    • 关闭非捕获组
    • \Z
      字符串结尾
    |

    输出

    ['16', '160', '1,2']
    

    谢谢你的回复。我不太明白您为什么在我的问题中提到“100不是一个数字,也不匹配\d”。关于第二个查询,我写了两个连续的'\d',因此它应该显示任何匹配两个连续数字的内容,没有?
    [\d],\d]
    将不匹配100,10。只有一位数字。相反,第二部分将匹配任何以2位开始但不后跟冒号的数字,例如响应的10,40120kappathanks。我不太明白您为什么在我的问题中提到“100不是一个数字,也不匹配\d”。关于第二个查询,我写了两个连续的'\d',因此它应该显示任何匹配两个连续数字的内容,没有?
    [\d],\d]
    将不匹配100,10。只有一位数字。相反,第二部分将匹配任何以2位开始但不后跟冒号的数字,例如10,40120。顺便问一下,我真的需要非捕获组吗?我复制/粘贴了另一个示例中的内容,但它似乎没有改变任何东西,对吗?@AnthonyHauser如果需要分组,可以使用
    ()
    将其设置为捕获组,但不需要捕获组值。这场比赛本身就足够了。如果不使用分组,则可以获得部分匹配。请参见,我需要“()”以便在末尾添加适用于这两个条件的“\Z”?“否则我就不明白你的例子了。”安托尼豪瑟说得对。如果不使用分组,则模式匹配
    ^\d{2,}
    \d\d\Z
    (因为它使用了在字符串开头已经匹配的re.match,您可以省略
    ^
    ),但为什么要添加“^”?不应搜索任何字符