在Python中,从一个文件到另一个文件从一组字符写到另一个

2024-09-28 19:30:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要阅读整个.txt文件,直到它找到字符'{{'(一行正好2个),从现在起,它应该将所有内容保存到另一个.txt文件,直到它满足'}}'。诀窍是那些角色不必在行乞线上,他们可以在任何地方。所以示例文件可能如下所示:

    blablabla {{zzzzz
zzzzzz
zzzz
zzz
zz
}}blabla

它应该得到所有的“z”。在python2中什么是最简单的方法?我发现了类似的问题,但没有什么能帮助我的案子。在


Tags: 文件txt角色示例内容地方字符zzz
3条回答

或者考虑使用如下方法:

import sys                                                                      


def save_lines(infile, outfile):                                                
    save = False                                                                
    for line in infile:                                                         
        if save:                                                                
            pos = line.find('}}')                                               
            if pos > -1:                                                        
                outfile.write(line[:pos] + '\n')                                
                save = False                                                    
            else:                                                               
                outfile.write(line)                                             
        else:                                                                   
            pos = line.find('{{')                                               
            if pos > -1:                                                        
                outfile.write('  -\n')                                        
                save = True                                                     
                outfile.write(line[pos + 2:])                                   
            else:                                                               
                pass                                                            


def test():                                                                     
    infile = open('tmp01.txt', 'r')                                             
    save_lines(infile, sys.stdout)                                              
    infile.close()                                                              


if __name__ == '__main__':                                                      
    test()                                                                      

罗布是对的。上述解决方案存在问题。在

并且,上面Rob给出的基于正则表达式的解决方案 对我来说是个不错的选择。在

这里有一个变化:

def save_lines(infile, outfile):
    bracket_pattern = re.compile(r'{{(.*?)}}', re.DOTALL)
    content = infile.read()
    for mo in bracket_pattern.finditer(content):
        outchars = mo.group(1)
        outfile.write('matched: "{}" at position {}\n'.format(
            outchars, mo.start()))

但是,根据您的需要,您可能还需要考虑 以下内容:(1)基于正则表达式的方法提供了 语法错误检查的灵活性很小。(2) 常规 表达式不支持递归语法,也就是说,如果 你需要解析的语法(我们讨论的是解析 问题)这里包含或扩展为包含嵌套语法 元素,正则表达式将不会有帮助。在

这是另一种基于有限状态机的解决方案。它 可能会为错误报告提供更多的灵活性。但是,是的 更长更复杂。这种复杂性是有代价的:(1) 开发时间(上面的正则表达式解决方案花了我很多时间 10~15分钟;这个FSM解决方案花了我几个小时);以及(2) 调试(这里有很多逻辑,大部分是if语句) 有很多方法会出错。在

因为它是基于有限状态机的,所以也不能扩展 (毫不困难地)支持处理嵌套的语法 (递归)构造。为此,您可能需要查看一个解析器 发电机。查看此列表: https://wiki.python.org/moin/LanguageParsing

从积极的一面来看,因为下面的代码是基于FSM的, 你可以画一个状态转换图来说明 假定代码在任何给定的情况下都可以接受(例如,只是 看到一个左大括号,里面有一个大括号 右花括号等)。在纸上,我把那张图画成 有向图(圆表示状态,圆之间的箭头表示 转换)。我觉得我做不到ascii艺术,所以 这是一个状态转换图的文本表示 可能看起来像:

^{pr2}$

代码如下:

#!/usr/bin/env python

"""
Synopsis:
    Search for and write out text content occuring between '{{' and '}}'.
Usage:
    python capture.py <infilename>
Args:
    1. Input file name
Options:
    None
Example:
    python capture.py some_file.txt
"""

import sys


(
    ST_start,
    ST_seen_left_bracket,
    ST_inside_brackets,
    ST_seen_right_bracket,
    ST_outside_brackets,
    ST_end,
) = range(1, 7)

Left_bracket = '{'
Right_bracket = '}'


class ReaderWriter(object):
    def __init__(self, infile, outfile):
        self.infile = infile
        self.outfile = outfile
        self.line = ''
        self.pos = 0
        self.inchar = None
        self.prevchar = None
        self.char_count = 0

    def get_char(self):
        if self.pos >= len(self.line):
            self.line = self.infile.readline()
            if not self.line:
                return None
            self.pos = 0
        self.prevchar = self.inchar
        inchar = self.line[self.pos]
        self.inchar = inchar
        self.pos += 1
        self.char_count += 1
        return inchar

    def write(self, outchars):
        #self.outfile.write('found: "{}"\n'.format(outchar))
        self.outfile.write(outchars)

    def write_prev_char(self):
        #self.outfile.write('found: "{}"\n'.format(self.prevchar))
        self.outfile.write(self.prevchar)


def save_lines(infile, outfile):
    state = ST_start
    while True:
        if state == ST_start:
            reader_writer = ReaderWriter(infile, outfile)
            inchar = reader_writer.get_char()
            state = ST_outside_brackets
        elif state == ST_outside_brackets:
            if inchar == Left_bracket:
                inchar = reader_writer.get_char()
                state = ST_seen_left_bracket if inchar is not None else ST_end
            else:
                inchar = reader_writer.get_char()
                state = ST_outside_brackets if inchar is not None else ST_end
        elif state == ST_seen_left_bracket:
            if inchar == Left_bracket:
                reader_writer.write('found (pos {:d}): "'.format(
                    reader_writer.char_count))
                inchar = reader_writer.get_char()
                state = ST_inside_brackets if inchar is not None else ST_end
            else:
                inchar = reader_writer.get_char()
                state = ST_outside_brackets if inchar is not None else ST_end
        elif state == ST_inside_brackets:
            if inchar == Right_bracket:
                inchar = reader_writer.get_char()
                state = ST_seen_right_bracket if inchar is not None else ST_end
            else:
                reader_writer.write(inchar)
                inchar = reader_writer.get_char()
                state = ST_inside_brackets if inchar is not None else ST_end
        elif state == ST_seen_right_bracket:
            if inchar == Right_bracket:
                reader_writer.write('"\n')
                inchar = reader_writer.get_char()
                state = ST_outside_brackets if inchar is not None else ST_end
            else:
                reader_writer.write_prev_char()
                reader_writer.write(inchar)
                inchar = reader_writer.get_char()
                state = ST_inside_brackets if inchar is not None else ST_end
        elif state == ST_end:
            return
        else:
            pass


def main():
    args = sys.argv[1:]
    if len(args) != 1:
        sys.exit(__doc__)
    if args[0] == '-h' or args[0] == ' help':
        print __doc__
        sys.exit()
    infilename = args[0]
    infile = open(infilename, 'r')
    save_lines(infile, sys.stdout)
    infile.close()


if __name__ == '__main__':
    #import ipdb
    #ipdb.set_trace()
    main()

我会使用正则表达式,re.findall()

with open('/tmp/in') as input_file:
    with open('/tmp/out', 'w') as output_file:
        input = input_file.read()
        output_file.write(''.join(re.findall(r'(?s)(?<={{).*?(?=}})', input)))

分解:

  • with行打开相关的数据文件。你可能已经有这个了。在
  • input_file.read()创建一个包含文件内容的字符串。在
  • re.findall()的调用搜索:
    • {{,但从结果中排除它((?<={{))。在
    • 最短((?s))可能匹配到}}.*?
    • }},但从结果中排除它((?=}})
  • 调用''.join()将所有字符串粘贴在一起。在
  • output_file.write()的调用将结果存储到输出文件中。在

相关问题 更多 >