【问题标题】:Extracting numbers from a string using regex in python在python中使用正则表达式从字符串中提取数字
【发布时间】:2017-06-23 16:38:20
【问题描述】:

我有一个要解析的网址列表:

['https://www.richmondfed.org/-/media/richmondfedorg/press_room/speeches/president_jeff_lacker/2017/pdf/lacker_speech_20170303.pdf','http://www.federalreserve.gov/newsevents/speech/powell20160929a.htm','http://www.federalreserve.gov/newsevents/speech/fischer20161005a.htm']

我想使用正则表达式创建一个新列表,其中包含字符串末尾的数字和标点符号之前的任何字母(某些字符串包含两个位置的数字,如上面列表中的第一个字符串所示)。所以新列表看起来像:

['20170303', '20160929a', '20161005a']

这是我没有运气的尝试:

code = re.search(r'?[0-9a-z]*', urls)

更新:

跑步-

[re.search(r'(\d+)\D+$', url).group(1) for url in urls]

我收到以下错误 -

AttributeError: 'NoneType' object has no attribute 'group'

此外,如果有字母,这似乎不会在数字后面接一个字母..!

【问题讨论】:

标签: python regex fuzzywuzzy


【解决方案1】:
# python3

from urllib.parse import urlparse
from os.path import basename

def extract_id(url):
    path = urlparse(url).path
    resource = basename(path)
    _id = re.search('\d[^.]*', resource)
    if _id:
        return _id.group(0)

urls =['https://www.richmondfed.org/-/media/richmondfedorg/press_room/speeches/president_jeff_lacker/2017/pdf/lacker_speech_20170303.pdf','http://www.federalreserve.gov/newsevents/speech/powell20160929a.htm','http://www.federalreserve.gov/newsevents/speech/fischer20161005a.htm']

# /!\ here you have None if pattern doesn't exist ;) in ids list
ids = [extract_id(url) for url in urls]

print(ids)

输出:

['20170303', '20160929a', '20161005a']

【讨论】:

  • 这很好,除了示例中第一个字符串的输出没有跳过第一个 2017 - 输出是:['2017/pdf/lacker_speech_20170303', '20160929a', '20161005a ']
  • 你必须在正则表达式中改变了一些东西,因为现在它可以工作了,谢谢!
【解决方案2】:

你可以使用这个正则表达式(\d+[a-z]*)\.

regex demo

输出

20170303
20160929a
20161005a

【讨论】:

    【解决方案3】:

    给定:

    >>> lios=['https://www.richmondfed.org/-/media/richmondfedorg/press_room/speeches/president_jeff_lacker/2017/pdf/lacker_speech_20170303.pdf','http://www.federalreserve.gov/newsevents/speech/powell20160929a.htm','http://www.federalreserve.gov/newsevents/speech/fischer20161005a.htm']
    

    你可以这样做:

    for s in lios:
        m=re.search(r'(\d+\w*)\D+$', s)
        if m:
            print m.group(1)
    

    打印:

    20170303
    20160929a
    20161005a
    

    基于这个正则表达式:

    (\d+\w*)\D+$
      ^              digits
         ^           any non digits
            ^        non digits
               ^     end of string
    

    【讨论】:

    • 你看过预期的输出了吗?
    【解决方案4】:
    import re
    
    patterns = {
        'url_refs': re.compile("(\d+[a-z]*)\."),  # YCF_L
    }
    
    def scan(iterable, pattern=None):
        """Scan for matches in an iterable."""
        for item in iterable:
            # if you want only one, add a comma:
            # reference, = pattern.findall(item)
            # but it's less reusable.
            matches = pattern.findall(item)
            yield matches
    

    你可以这样做:

    hits = scan(urls, pattern=patterns['url_refs'])
    references = (item[0] for item in hits)
    

    references 提供给您的其他功能。你可以通过这种方式处理更多的东西,而且我想做得更快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-17
      • 1970-01-01
      • 2014-08-25
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      • 2010-10-14
      相关资源
      最近更新 更多