【问题标题】:Parse a text file with columns aligned with white spaces解析列与空格对齐的文本文件
【发布时间】:2014-05-14 10:25:30
【问题描述】:

我正在尝试解析一个文本文件,其中条目对齐为使用多个空格的列。 文本如下所示:

Blah blah, blah               bao     123456     
hello, hello, hello           miao    299292929  

我已经检查过它不是制表符分隔的。 这些条目实际上与多个空格对齐。

将文本分成单行没有问题,然后我还注意到数字序列后面有尾随空格。所以我现在拥有的是:

["Blah blah, blah               bao     123456     ",   
 "hello, hello, hello           miao    299292929  "]

期望的输出是:

[["Blah blah, blah", "bao", "123456"],
 ["hello, hello, hello", "miao", "299292929"]]

【问题讨论】:

    标签: python text-parsing string-parsing


    【解决方案1】:

    您可以使用re.split(),并使用\s{2,} 作为分隔符模式:

    >>> l = ["Blah blah, blah               bao     123456     ",   
    ...      "hello, hello, hello           miao    299292929  "]
    >>> for item in l:
    ...     re.split('\s{2,}', item.strip())
    ... 
    ['Blah blah, blah', 'bao', '123456']
    ['hello, hello, hello', 'miao', '299292929']
    

    \s{2,} 匹配 2 个或更多后续空白字符。

    【讨论】:

    • 值得一提的是这怎么会失败
    • @goncalopp 好的,您的意思是在一个条目中有 2 个或更多空格吗?
    • 到目前为止,我还没有在多个空格是单个条目的一部分的任何情况下运行。感谢您对此进行调查。
    【解决方案2】:

    如果您知道每个字段的宽度,那就很容易了。第一个字段是 30 个字符宽,第二个是 8 个字符,最后一个是 11 个字符。所以你可以这样做:

    line = 'Blah blah, blah               bao     123456     '
    parts = [line[:30].strip(), line[30:39].strip(), line[38:].strip()]
    

    【讨论】:

      【解决方案3】:

      使用重新模块

      import re
      l1 = re.split('  +', l[0])
      l2 = re.split('  +', l[1])
      print [l1.remove(''), l2.remove('')]
      

      【讨论】:

        【解决方案4】:

        您可以简单地按索引拆分。您可以对索引进行硬编码,也可以检测它们:

        l=["Blah blah, blah               bao     123456     ",   
           "hello, hello, hello           miao    299292929  "]
        
        def detect_column_indexes( list_of_lines ):
            indexes=[0]
            transitions= [col.count(' ')==len(list_of_lines) for col in zip(*list_of_lines)]
            last=False
            for i, x in enumerate(transitions):
                if not x and last:
                    indexes.append(i)
                last=x
            indexes.append( len(list_of_lines[0])+1 )
            return indexes
        
        def split_line_by_indexes( indexes, line ):
            tokens=[]
            for i1,i2 in zip(indexes[:-1], indexes[1:]): #pairs
                tokens.append( line[i1:i2].rstrip() )
            return tokens
        
        indexes= detect_column_indexes( l )
        parsed= [split_line_by_indexes(indexes, line) for line in l] 
        print indexes
        print parsed
        

        输出:

        [0, 30, 38, 50]
        [['Blah blah, blah', 'bao', '123456'], ['hello, hello, hello', 'miao', '299292929']]
        

        显然,无法区分每个列上的尾随空格 - 但您可以使用 rstrip 而不是 strip 来检测前导空格。

        此方法并非万无一失,但比检测两个连续的空格更稳健。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-05-23
          • 2021-09-08
          • 2018-07-07
          • 2016-07-29
          相关资源
          最近更新 更多