Python:搜索文本文件

时间:2015-07-07 03:07:21

标签: python

我有一个以下格式的文本文件:

XXXX Testing123
    YYYY hellow
    ZZZZ worldd
AAAA Testing456
    BBBB heyyy
    YYYY YoYo
AAAA Testing789
    CCCC hezzz
    YYYY hellow

这是我的文字搜索代码:

for line in open('test.txt')
     a = "XXXX"
     b = "\t" + "YYYY"
     if a in line:
        print line
     if b in line:
        print line

以上打印出来:

XXXX Testing123
   YYYY YoYo

但我想要的是:

XXXX Testing123
  YYYY hellow

我知道如何在Python中搜索这个吗?

基本上我需要先搜索XXXX,后续字段YYYY应该在此部分之下。如果在XXXX下找不到YYYY,则返回未找到而不是继续查看。

6 个答案:

答案 0 :(得分:3)

您可以制作一个标记,显示您是否在“XXXX”部分。如果是,则使flag = 1,否则使flag = 0。此外,你需要区分两种行。

a = "XXXX"
b = "\t" + "YYYY"
flag = 0
for line in open('test.txt'):
    if line[0] == '\t':
        if flag and b in line:
            print line,
    else:        
        if a in line:
            flag = 1
            print line,
        else:
            flag = 0

答案 1 :(得分:2)

如果这些是您的文本文件中的行,您可以像这样匹配它们:

import re
print (re.findall(r'XXXX T\w+', 'XXXX Testing123 any text here'))
print (re.findall(r'YYYY h\w+', 'YYYY hellow any text here'))

输出匹配:

['XXXX Testing123']
['YYYY hellow']

答案 2 :(得分:2)

鉴于此文件:

XXXX Testing123
    YYYY hellow
    ZZZZ worldd
AAAA Testing456
    BBBB heyyy
    YYYY YoYo

您可以在mmap文件中使用正则表达式:

import re
import mmap

with open(fn, 'r+') as f:
    mm=mmap.mmap(f.fileno(), 0)
    for m in re.finditer(r'^(XXXX.*?^\s+YYYY.*?)$', mm, flags=re.M | re.S):
        print m.group(1)

如果您只想要YYYY组,请拆分正则表达式:

with open(fn, 'r+') as f:
    mm=mmap.mmap(f.fileno(), 0)
    for m in re.finditer(r'^(XXXX.*?)^(\s+YYYY.*?)$', mm, flags=re.M | re.S):
        print m.group(2)

如果您想丢失领先的空间,请使用:

    for m in re.finditer(r'^(XXXX.*?)^\s+(YYYY.*?)$', mm, flags=re.M | re.S):

如果它是一个您完全可以在内存中使用的文件,则可以跳过mmap并使用f.read()

将文件读入内存

根据您的评论,您可以修改正则表达式以更准确地捕获您要查找的内容。

鉴于文件:

XXXX Testing123
    YYYY hellow
    ZZZZ worldd
AAAA Testing456
    BBBB heyyy
    YYYY YoYo
XXXX Testing123
    ZZZZ worldd
AAAA Testing456
    BBBB heyyy
    YYYY YoYo
XXXX Testing123 2
    YYYY hellow
    ZZZZ worldd

Demo regex

在Python中:

with open(fn, 'r+') as f:
    mm=mmap.mmap(f.fileno(), 0)
    for m in re.finditer(r'^XXXX.*\n^\s+(YYYY.*)', mm, flags=re.M ):
        print m.group(1)

打印:

YYYY hellow
YYYY hellow

您还可以使用两个元素deque并测试每一行的所需条件:

from collections import deque
with open(fn) as f:
    d=deque(maxlen=2)
    d.append(next(f))
    for line in f:
        d.append(line)
        if d[0].startswith('XXXX') and 'YYYY' in d[1]:
            print d

打印:

deque(['XXXX Testing123\n', '    YYYY hellow\n'], maxlen=2)
deque(['XXXX Testing123 2\n', '    YYYY hellow\n'], maxlen=2)

答案 3 :(得分:1)

import re    

printY = False
for line in open('test.txt').read().split('\n'):
    if re.match('^XXXX (.*?)$', line):
        print(line)
        printY = True
    elif re.match('^[A-Z]{4} (.*?)$', line):
        printY = False
    elif re.match('^\tYYYY (.*?)$', line):
        if printY:
            print(line)

您可以阅读有关正则表达式here的更多信息。

答案 4 :(得分:1)

我认为变量应该定义外部循环。如果你想找到XXXX并随后找到YYYY,那么你应该同时检查两行。下面的代码对我有用。

a = 'XXXX'
b = '\tYYYY'
with open('test.txt') as f:
    for line in f:
        next_line = next(f)
        if a in line and b in next_line:
            print line
            print next_line

欢迎任何问题

答案 5 :(得分:0)

看起来你需要像XPath一样定义一个查询。在最简单的形式中,查询可以是一个列表:['XXXX','YYYY']来搜索树中的分支。

以下是实现查询的代码:

def search(f, query):
    level = 0
    stack = []

    four_spaces, tab = ' '*4, '\t'
    for line in f:
            # First get the line indent level
            indents = 0
            while True:
                    if line.startswith(four_spaces):
                            indents += 1
                            line = line[4:]
                    elif line.startswith(tab):
                            indents += 1
                            line = line[1:]
                    else:
                            break
            if indents > level:
                    continue
            elif indents < level:
                    level = indents
                    stack = stack[:level]
            if line.startswith(query[level]):
                    stack.append(line)
                    level += 1
                    if level==len(query):
                            printResult(stack)
                            # clear the stack
                            level = 0
                            stack = []
            print level, indents, stack

def printResult(result):
        for i, line in enumerate(result):
                print "\t"*i + line


f = open('test.txt', 'r')
search(f, ['XXXX', 'YYYY', 'ZZZZ'])

将查询['XXXX', 'YYYY', 'ZZZZ'] test.txt指定为

XXXX Testing123
    YYYY foo
            MMMM bar
    YYYY hellow
            ZZZZ world
    ZZZZ abdkd
            YYYY dfkjd
    ZZZZ dkfdjk
AAAA Testing456
        BBBB heyyy
        YYYY YoYo
XXXX Testing789
        YYYY foo
                MMMM dk
        YYYY dkf
                ZZZZ dkd
                        KKKK kdf

它产生:

XXXX Testing123
    YYYY hellow
        ZZZZ world
XXXX Testing789
    YYYY dkf
        ZZZZ dkd