2014-07-26 2 views
1

의 특정 초기 문자열로 행이 같은 탭으로 구분 된 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 

을 시도했지만 작동하지 않았다.

답변

1

당신은 빠른 매칭 및 검색을위한 지점으로 정규 표현식을 사용할 수 있습니다 가능한 문구, re.escape을 사용하여 특수 문자를 이스케이프 처리합니다. 이 경우 표현식은 aaa|bbb입니다. pattern.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.txtoutput.txt 앞에두고, 전자가 없으면 후자가 생성되지 않도록합니다. 그리고 마침내 이것이 발전기와 람다없이 가장 멋지게 보인다.

+0

@Antti_Haapala 감사합니다! 첫 번째 방법이 효과적입니다. 그러나 두 번째 방법은 "목록 개체에 시작 속성이 없습니다"라는 오류 메시지가 표시됩니다. – user3123767

+0

코드에서 'row' ->'row [column]'이 (가) 변경되는 것을 잊어 버렸습니다. –

+0

@Antii_Haapala 정말 고마워! :) – user3123767

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']] 
1

당신은

>>> 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 

긍정적 예측이 있는지 여부를 확인하는 데 사용됩니다 이것에 대한 파이썬의 re 모듈을 사용할 수 엘 ine에는 특정 문자열이 들어 있습니다. 위의 정규식은 aaa 또는 bbb으로 시작하는 세 번째 열이있는 행을 확인합니다. 예이면 해당 줄이 인쇄됩니다.

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) 

코드는 모두에서 정규 표현식을 빌드 : 일반적인 경우

당신은이 정규식 코드를 시도 할 수

,

>>> 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 
+0

@Avinash_Raj 감사합니다!그러나 이것은 input.txt를 가져 와서 output.txt처럼 출력을 저장하는 것처럼 보이지 않습니다. 그런 목적으로 어떻게 편집해야합니까? – user3123767