簡體   English   中英

Python:搜索文本文件

[英]Python: search text file

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

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,則返回not found而不是繼續查找。

您可以標記顯示您是否在“ 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

如果這些是文本文件中的行,則可以像這樣進行匹配:

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

給定此文件:

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

演示正則表達式

在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

您還可以使用兩個元素的雙端隊列,並針對所需條件測試每一行:

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

您可以在此處閱讀更多有關正則表達式的信息

我想變量應該定義外部循環。 如果要查找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

任何問題歡迎

看起來您需要像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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM