【问题标题】:String split on new line, tab and some number of spaces在新行、制表符和一些空格上拆分字符串
【发布时间】:2012-09-14 01:52:58
【问题描述】:

我正在尝试对一组看起来像这样的不规则数据执行字符串拆分:

\n\tName: John Smith
\n\t  Home: Anytown USA
\n\t    Phone: 555-555-555
\n\t  Other Home: Somewhere Else
\n\t Notes: Other data
\n\tName: Jane Smith
\n\t  Misc: Data with spaces

我想将其转换为元组/字典,稍后我将在冒号: 上拆分,但首先我需要摆脱所有额外的空格。我猜正则表达式是最好的方法,但我似乎无法找到一个有效的方法,下面是我的尝试。

data_string.split('\n\t *')

【问题讨论】:

    标签: python regex split


    【解决方案1】:

    只需使用.strip(),它会在拆分时为您删除所有空格,包括制表符和换行符。然后可以使用data_string.splitlines() 来完成拆分本身:

    [s.strip() for s in data_string.splitlines()]
    

    输出:

    >>> [s.strip() for s in data_string.splitlines()]
    ['Name: John Smith', 'Home: Anytown USA', 'Phone: 555-555-555', 'Other Home: Somewhere Else', 'Notes: Other data', 'Name: Jane Smith', 'Misc: Data with spaces']
    

    您现在甚至可以在: 上内联拆分:

    >>> [s.strip().split(': ') for s in data_string.splitlines()]
    [['Name', 'John Smith'], ['Home', 'Anytown USA'], ['Phone', '555-555-555'], ['Other Home', 'Somewhere Else'], ['Notes', 'Other data'], ['Name', 'Jane Smith'], ['Misc', 'Data with spaces']]
    

    【讨论】:

    • 效果非常好,List comprehension 的语法我以前没有见过,所以我想我必须阅读它。
    【解决方案2】:
    >>> for line in s.splitlines():
    ...     line = line.strip()
    ...     if not line:continue
    ...     ary.append(line.split(":"))
    ...
    >>> ary
    [['Name', ' John Smith'], ['Home', ' Anytown USA'], ['Misc', ' Data with spaces'
    ]]
    >>> dict(ary)
    {'Home': ' Anytown USA', 'Misc': ' Data with spaces', 'Name': ' John Smith'}
    >>>
    

    【讨论】:

      【解决方案3】:

      你可以用一块正则表达式石杀死两只鸟:

      >>> r = """
      ... \n\tName: John Smith
      ... \n\t  Home: Anytown USA
      ... \n\t    Phone: 555-555-555
      ... \n\t  Other Home: Somewhere Else
      ... \n\t Notes: Other data
      ... \n\tName: Jane Smith
      ... \n\t  Misc: Data with spaces
      ... """
      >>> import re
      >>> print re.findall(r'(\S[^:]+):\s*(.*\S)', r)
      [('Name', 'John Smith'), ('Home', 'Anytown USA'), ('Phone', '555-555-555'), ('Other Home', 'Somewhere Else'), ('Notes', 'Other data'), ('Name', 'Jane Smith'), ('Misc', 'Data with spaces')]
      >>> 
      

      【讨论】:

      • 相当不错,但是您的[ \t]* 没有做任何事情; (.+) 将始终吃掉尾随空格(如果有的话)。你可以这样做:(.+?)[ \t]*$。不情愿的量词允许它提前停止,而$ 确保它仍然消耗整行。
      【解决方案4】:

      如果您查看the documentationstr.split

      如果 sep 未指定或为 None,则应用不同的分割算法:连续的空格被视为单个分隔符,如果字符串有前导或尾随,结果将在开头或结尾不包含空字符串空白。因此,使用 None 分隔符拆分空字符串或仅包含空格的字符串将返回 []。

      换句话说,如果您想弄清楚将什么传递给split 以将'\n\tName: Jane Smith' 传递给['Name:', 'Jane', 'Smith'],则什么都不传递(或不传递)。

      这几乎解决了你的整个问题。剩下两部分。

      首先,您只有两个字段,第二个字段可以包含空格。所以,你只想要一个分裂,而不是尽可能多的分裂。所以:

      s.split(None, 1)
      

      接下来,你还有那些讨厌的冒号。但是你不需要分裂它们。至少鉴于您向我们展示的数据,冒号始终出现在第一个字段的末尾,之前没有空格,之后始终有空格,因此您可以将其删除:

      key, value = s.split(None, 1)
      key = key[:-1]
      

      当然,还有一百万种其他方法可以做到这一点;这只是看起来最接近您已经尝试过的那个。

      【讨论】:

        【解决方案5】:

        你可以用这个

        string.strip().split(":")
        

        【讨论】:

          【解决方案6】:

          正则表达式并不是真正适合这里工作的最佳工具。正如其他人所说,使用str.strip()str.split() 的组合是要走的路。这是一个单一的班轮:

          >>> data = '''\n\tName: John Smith
          ... \n\t  Home: Anytown USA
          ... \n\t    Phone: 555-555-555
          ... \n\t  Other Home: Somewhere Else
          ... \n\t Notes: Other data
          ... \n\tName: Jane Smith
          ... \n\t  Misc: Data with spaces'''
          >>> {line.strip().split(': ')[0]:line.split(': ')[1] for line in data.splitlines() if line.strip() != ''}
          {'Name': 'Jane Smith', 'Other Home': 'Somewhere Else', 'Notes': 'Other data', 'Misc': 'Data with spaces', 'Phone': '555-555-555', 'Home': 'Anytown USA'}
          

          【讨论】:

            【解决方案7】:

            我不得不在换行符 (\n) 和制表符 (\t) 上拆分字符串。我所做的是首先将 \n 替换为 \t 然后拆分为 \t

            example_arr = example_string.replace("\n", "\t").split("\t")
            

            【讨论】:

              猜你喜欢
              • 2015-11-26
              • 1970-01-01
              • 2014-02-15
              • 1970-01-01
              • 1970-01-01
              • 2017-09-03
              • 2015-04-14
              • 1970-01-01
              相关资源
              最近更新 更多