输出具有某个特定列的特定初始字符串的行

时间:2014-07-26 06:09:14

标签: python tab-delimited-text

我有一个制表符分隔的txt文件,如下所示:

A   B   aaaKP
C   D   bbbZ
E   F   cccLL

这是制表符分隔的。

如果

phrase = aaa or bbb
column = 3

然后我只希望那些第3列以aaa或bbb

开头的行

输出

A   B   aaaKP
C   D   bbbZ

我有一个只有一个短语的代码。

phrase, column = 'aaa', 3
fn = lambda l : len(l) >= column and len(l[column-1]) >= len(phrase) and phrase == l[column-1][:len(phrase)]
fp = open('output.txt', 'w')
fp.write(''.join(row for row in open('input.txt') if fn(row.split('\t'))))
fp.close()

但如果有多个短语..我试过

phrase, column = {'aaa','bbb'}, 3

但它不起作用。

3 个答案:

答案 0 :(得分:1)

你可以使用python的re模块,

>>> import re
>>> data = """A   B   aaaKP
... C   D   bbbZ
... E   F   cccLL"""
>>> m = re.findall(r'^(?=\S+\s+\S+\s+(?:aaa|bbb)).*$', data, re.M)
>>> for i in m:
...     print i
... 
A   B   aaaKP
C   D   bbbZ

正向前瞻用于检查该行是否包含特定字符串。上述正则表达式检查第三列以aaabbb开头的行。如果是,则打印相应的行。

你也可以试试这个正则表达式代码,

>>> s = """A    B       aaaKP
... C   D       bbbZ
... E   F       cccLL
... """
>>> m = re.findall(r'^(?=\S+\t\S+\t(?:aaa|bbb)).*$', s, re.M)
>>> for i in m:
...     print i
... 
A   B   aaaKP
C   D   bbbZ

答案 1 :(得分:1)

一般情况下,您可以使用带分支的正则表达式进行快速匹配和搜索:

import re

phrases = [ 'aaa', 'bbb' ]
column = 3

pattern = re.compile('|'.join(re.escape(i) for i in phrases))
column -= 1

with open('input.txt') as inf, open('output.txt', 'w') as outf:
    for line in inf:
        row = line.split('\t')
        if pattern.match(row[column]):
            outf.write(line)

代码使用re.escape来转义特殊字符,从所有可能的短语构建正则表达式。在这种情况下,结果表达式为aaa|bbbpattern.match匹配模式的字符串的开头(匹配必须从第一个字符开始)。

但是,如果必须只匹配字符串的开头与固定短语,请注意startswith接受元组,这是最快的代码:

 phrases = [ 'aaa', 'bbb' ]
 column = 3

 phrase_tuple = tuple(phrases)
 column -= 1

 with open('input.txt') as inf, open('output.txt', 'w') as outf:
     for line in inf:
         row = line.split('\t')
         if row[column].startswith(phrase_tuple):
             outf.write(line)

此外,它演示了使用上下文管理器打开文件,在input.txt之前打开output.txt,这样如果前者不存在,后者就不会被创建。最后表明,如果没有任何生成器和lambda,这看起来最好。

答案 2 :(得分:0)

<强>解决方案:

#!/usr/bin/env python


import csv
from pprint import pprint


def read_phrases(filename, phrases):
    with open(filename, "r") as fd:
        reader = csv.reader(fd, delimiter="\t")
        for row in reader:
            if any((row[2].startswith(phrase) for phrase in phrases)):
                yield row


pprint(list(read_phrases("foo.txt", ["aaa"])))
pprint(list(read_phrases("foo.txt", ["aaa", "bbb"])))

示例:

$ python foo.py
[['A', 'B', 'aaaKP']]
[['A', 'B', 'aaaKP'], ['C', 'D', 'bbbZ']]