【问题标题】:How to split elements of list with regex如何使用正则表达式拆分列表元素
【发布时间】:2013-06-21 14:02:35
【问题描述】:

鉴于此列表:

['MIA', 'BOS', '08:17 AM', '-107', '-103', '08:17 AM', '+1 -111', '-1 +103', u'91', u'93']

我想在空间上拆分+1 -111-1 +103 以获得以下结果:

['MIA', 'BOS', '08:17 AM', '-107', '-103', '08:17 AM', '+1', '-111', '-1', '+103', u'91', u'93']

这是我需要的正则表达式:

(?<=\d)\s(?=[-+]\d\d\d)

但显然我不知道如何将其应用于列表。显然,切片的解决方案,如始终拆分列表的nth 元素不是受欢迎的选项。我更喜欢这样更有效率。

【问题讨论】:

    标签: python regex python-2.7


    【解决方案1】:

    使用生成器可以非常有效,特别是对于大量输入并且如果您打算在迭代后丢弃结果(并且比使用中间列表更优雅):

    def split_elements(list_, regex):
        for element in list_:
            for sub_element in re.split(regex, element):
                yield sub_element
    
    output = [x for x in split_elements(input, regex)]
    

    对于示例输入:

    >>> l = ['MIA', 'BOS', '08:17 AM', '-107', '-103', '08:17 AM', 
             '+1 -111', '-1 +103', u'91', u'93']
    
    >>> list(split_elements(l, r'(?<=\d)\s(?=[-+]\d\d\d)'))
    ['MIA', 'BOS', '08:17 AM', '-107', '-103', '08:17 AM', '+1', '-111', '-1',
     '+103', u'91', u'93']
    

    这与 Jon Clements 的回答中使用的技术几乎相同,没有 itertools(单行可能会在几周后变得难以阅读)。

    【讨论】:

      【解决方案2】:

      这是使用列表推导的一个选项:

      import re
      
      lst = ['MIA', 'BOS', '08:17 AM', '-107', '-103', '08:17 AM', '+1 -111', '-1 +103', u'91', u'93']
      result = [s for x in lst for s in re.split(r'(?<=\d)\s(?=[-+]\d\d\d)', x)]
      

      结果:

      >>> result
      ['MIA', 'BOS', '08:17 AM', '-107', '-103', '08:17 AM', '+1', '-111', '-1', '+103', u'91', u'93']
      

      或者就地修改列表:

      for i in range(len(lst)-1, -1, -1):
          lst[i:i+1] = re.split(r'(?<=\d)\s(?=[-+]\d\d\d)', lst[i])
      

      请注意,从列表末尾循环到前面很重要。

      【讨论】:

        【解决方案3】:

        使用您现有的re,您可以使用以下内容来展平单个元素拆分:

        import re
        from itertools import chain
        
        some_list = ['MIA', 'BOS', '08:17 AM', '-107', '-103', '08:17 AM', '+1 -111', '-1 +103', u'91', u'93']
        print list(chain.from_iterable(re.split('(?<=\d)\s(?=[-+]\d\d\d)', s) for s in some_list))
        # ['MIA', 'BOS', '08:17 AM', '-107', '-103', '08:17 AM', '+1', '-111', '-1', '+103', u'91', u'93']
        

        【讨论】:

        • ..from_iterable(imap(re.compile(r'(?&lt;=\d)\s(?=[-+]\d\d\d)').split, some_list)))
        【解决方案4】:

        不确定这是否是最有效的方法,但是:

        output = []
        for x in input:
            if re.search('(?<=\d)\s(?=[-+]\d\d\d)', x):
                output += x.split(" ")
        

        应该可以。

        【讨论】:

          猜你喜欢
          • 2020-08-07
          • 2021-04-23
          • 1970-01-01
          • 1970-01-01
          • 2020-08-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多