【问题标题】:get percent of matched string with regex使用正则表达式获取匹配字符串的百分比
【发布时间】:2018-05-05 00:03:52
【问题描述】:

我需要获取与提供的字符串匹配的正则表达式的百分比,例如。我有正则表达式:

^[A-Za-z]{1,2}[0-9]{4}[a-zA-Z]{1,3}$

试图匹配包含一个或两个字符、四个数字和一到三个字符的字符串。现在,如果我将此正则表达式应用于aa1234bb,它将匹配,但如果使用aa1234,它将不匹配。

我想要的是在将正则表达式应用于字符串之后,它应该返回字符串与正则表达式匹配的百分比,例如对于aa1234,如果我们考虑最多 10 个字符,它与给定的正则表达式匹配几乎 70%会有任何匹配的字符串。

【问题讨论】:

  • 我能想到的唯一方法就是计算组数。尝试将您的正则表达式扩展为 ^([a-z])([a-z])?(\d)(\d)(\d)(\d)([a-z])([a-z])?([a-z])?$ 并计算组数。否则,只需进行字符串和匹配长度比较。
  • Python re 模块匹配对象有一个 span() 方法返回匹配的跨度。您可以将其与总字符串长度进行比较。
  • 1234bb 的百分比是多少? aabb 怎么样?如果您想要的不是严格的从左到右匹配,这将变得更加困难。
  • @Kevin 它也应该给 70%

标签: python regex


【解决方案1】:

我想不出这在完全通用(即接受任何正则表达式)和完全在re 内是如何实现的。

一种简单但可能足够的方法是二分搜索。这假定您的正则表达式始终绑定到字符串的前面。下面是一个粗略的、未经测试的例子来展示这个想法。显然,对于长字符串,它可能会多次执行正则表达式。

def percent_match(regex, target):
    left = 0
    right = len(target) - 1
    current = right // 2
    while left < right:
        if regex.match(target[left:right]):
            left = current
        else:
            right = current
        current = (right - left) // 2
    return m / len(target)

另一方面,如果您只需要使用一个正则表达式来执行此操作,那么@ctwheels 方法可能最有意义。

【讨论】:

    【解决方案2】:

    这是我的尝试:

    import re
    full_pattern = re.compile(r"^([a-z][a-z]?)?(\d\d\d\d)?([a-z][a-z]?[a-z]?)?$")
    num_pos_matches = 3 # 9 groups in our reg
    
    list_of_test_cases = ["aa1234bb","aa1234","1234bb","aabb","+pow","aa","1234","b5555bb"]
    
    def get_match_percentage(in_str):
      m = re.match(full_pattern,in_str)
      if m == None:
        return 0
      m_g = m.groups()
    
      counter = 0
      for x in m_g:
        if x == None:
          counter+=1
      return round((1 - counter/num_pos_matches) * 100,2)
    
    # print some tests
    for test_case in list_of_test_cases:
      print(test_case, " matched ",get_match_percentage(test_case), "% of the ",num_pos_matches, " Regex groups")
    

    输出:

    aa1234bb  matched  100.0 % of the  3  Regex groups
    aa1234  matched  66.67 % of the  3  Regex groups
    1234bb  matched  66.67 % of the  3  Regex groups
    aabb  matched  66.67 % of the  3  Regex groups
    +pow  matched  0 % of the  3  Regex groups
    ....
    

    我认为肯定有一些失败的案例,例如我希望"123dfg"33.33%,但它会产生

    123dfg  matched  0 % of the  3  Regex groups
    

    所以你可以稍微按摩一下来解决这些问题。很多功劳归于@ctwheels 团体的想法。

    【讨论】:

      猜你喜欢
      • 2012-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-09
      • 2019-07-07
      • 1970-01-01
      • 2017-11-19
      • 2014-12-30
      相关资源
      最近更新 更多