代码之家  ›  专栏  ›  技术社区  ›  Gianni Spear

Python中使用缩写的正则表达式

  •  1
  • Gianni Spear  · 技术社区  · 5 年前

    我有几千行,比如:

    “序列1,-2,-1,2,1,-2,-1,2,…,和g.f.(1-2x)/(1+x^2)有一个(n)=cos(Pi*n/2)-2*sin(Pi*n/2)- 保罗·巴里 ,2004年10月18日“

    我需要找到日期的位置,如果有的话,比如“03年8月”。为此,我写了一个函数 _find_all_positions

    def _add_zero(value: int) -> str:
       """add zero to number with digits < 2"""
       value_str = str(value)
       digits = len(value_str)
       if digits < 2:
           value_str = '0' + value_str
       return value_str
        
    def get_date() -> list:
        """Get dates for author(s) search, from ' Jan 01' to ' Dec 31' """
        dates = list()
        months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
        for month in months:
            for day in range(1, 32):
                dates.append(' ' + month + ' ' + ParserUtilities._add_zero(day))
        return dates
    
    def _find_all_positions(string: str, sub: str):
        """Find all occurrences of a substring in a string"""
        start = 0
        while True:
            start = string.find(sub, start)
            if start == -1:
                return
            yield start
            start += len(sub)  # use start += 1 to find overlapping matches
    

    这项任务很慢,我想知道你是否同意 Regular Expression 有可能加快搜索速度

    2 回复  |  直到 5 年前
        1
  •  2
  •   Daniel    5 年前

    可以将所有月份放在一个正则表达式中:

    def find_all_positions(text):
        for match in re.finditer('(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ([012][0-9]|30|31)', text):
            yield math.start()
    
        2
  •  1
  •   Mustafa Aydın    5 年前

    这里有一个解决问题的方法 regex 看起来是一个大写字母,后面是两个小写字母。然后需要一个空格和两位数字:

    import calendar
    import re
    
    # first one is empty string, we slice that
    months = tuple(calendar.month_abbr)[1:]  # ("Jan", "Feb", ...)
    
    pattern = re.compile(r"[A-Z][a-z]{2} \d{2}")
    
    result = [match.start()
              for match in re.finditer(pattern, seq)
              if match.group().startswith(months)]
    

    这给了 [111] 对于问题中的字符串。 re.finditer 查找所有可能的匹配项并返回一个迭代器,迭代器在迭代时给出 re.Match 对象谁的 start 方法查询以获取匹配项的位置。自从 [A-Z][a-z]{2} 可以在几个月之外进行比赛,我们会检查比赛是否以任何一个月开始。 result 如果找不到匹配项,则将为空列表。

    推荐文章