【问题标题】:How to find substring in file?如何在文件中查找子字符串?
【发布时间】:2011-08-13 19:52:34
【问题描述】:

如何仅使用 read(1) 在二进制文件中查找字符串? 例如,我想在文件中找到字符串“abst”的位置(不加载到内存)? 这是工作,但非常原始:

#!/usr/bin/python2 f = open("/tmp/rr", "rb") f.seek(0) 续 = 1 同时(续): a1 = f.read(1) 如果 a1 == 'a': a2 = f.read(1) 如果 a2 == 'b': a3 = f.read(1) 如果 a3 == 's': a4 = f.read(1) 如果 a4 == 't': 找到=真 续 = 0

【问题讨论】:

  • 如果文件包含aabst怎么办?
  • 为什么要只使用read(1)?这是作业吗?

标签: python


【解决方案1】:

使用mmap 搜索具有恒定内存需求的文件:

import mmap
with open('/tmp/rr', 'rb') as f:
  m = mmap.mmap(f.fileno(), 0, mmap.MAP_PRIVATE, mmap.PROT_READ)
  position = m.index('abst')

【讨论】:

  • 更新为 position 而不是 found。如果未找到该字符串,结果将为 -1。
【解决方案2】:

这对你有用吗?

#!/usr/bin/python

string = "abst"
f = open("/tmp/rr", "rb")
f.seek(0)

cont = 1
idx = 0
while True:
    c = f.read(1)
    if c == '':
        break
    if c == string[idx]:
        idx += 1
    elif c == string[0]:
        idx = 1
    else:
        idx = 0
    if idx == len(string):
        print "Found"
        break

【讨论】:

    【解决方案3】:

    您可以使用字符串查找方法查找子字符串。

    content = file.read()
    name = 'abst'
    if name in content:
        slice = content.find(name)
        slice = slice, slice + len(name)
    

    read(1)-方法绝对没有意义。 #see edit

    编辑:更高效的记忆

    def find(file, name):
        length = len(name)
        part = file.read(length)
        i = 0
        while True:
            if part == name:
                break
            char = file.read(1)
            if not char:
                return
            part = part[1:] + char
            i += 1
        return i, i + length, part
    

    我明白了,使用read(1) 并不是那么无意义。

    【讨论】:

    • 这种方式需要文件大小的内存,完全不需要搜索。
    • @philhag:mmap 方法不是也需要将文件存储在内存中吗?
    【解决方案4】:

    如果您的文件大部分都充满了 'a',或者与您正在搜索的字符串中的第一个字符相对应的任何字符,则此算法将耗费大量时间,否则效果很好。

    check = 'abst'
    col=1
    row=1
    location = (-1, -1)
    
    with open("/tmp/rr", 'rb') as p:
        ch = p.read(1)
        while(ch != ""):
            if ch == check[0]:
                st = p.read(len(check)-1)
                if ch+st == check:
                    location = (row, col)
                    break
                else:
                    p.seek(-len(check)+1, 1)
    
            ch = p.read(1)
            col+=1
    
            if ch == '\n':
                col=0
                row+=1
    
    print("loc: {}, {}".format(*location))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-01
      • 1970-01-01
      • 2021-04-21
      • 2020-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多