Python 在文本中查找特定代码块

Python 在文本中查找特定代码块,python,tkinter,readline,Python,Tkinter,Readline,到目前为止,我有以下代码: import sys from Tkinter import * import tkFileDialog from tkFileDialog import askopenfile # Open dialog box fen1 = Tk() # Create window fen1.title("Optimisation") # Window title menu1 = Menu

到目前为止,我有以下代码:

import sys
from Tkinter import *
import tkFileDialog
from tkFileDialog import askopenfile # Open dialog box


fen1 = Tk()                              # Create window
fen1.title("Optimisation")               # Window title

menu1 = Menu(fen1)

def open():
    filename = askopenfile(filetypes=[("Text files","*.txt")], mode='r')

filename.seek(0)
    numligne = 0
    line     = []
    ok       = 0
    k        = -1

    while (ok == 0)  &  (k == -1):
    line = filename.readline()
    k    = line.find( "*load" )
    if k == 0 :
        l = filename.readlines()

fen1.mainloop()
我正在搜索的文本文件的格式如下所示:

*test
1 2 3 4

*load
2 7 200
3 7 150

*stiffness
2 9 8 7

etc..
到目前为止,我已经找到了以“*load”开头的行,但我希望将“*load”和“*stiffness”之间的值分配给变量,如a、b、c。我的问题是,在这个加载部分中,可能有几行,每次我都需要检测每一行,拆分行中的值并给它们一个名称。如果有人能帮我解释一个循环或类似的东西,我将非常感激!谢谢大家!

更新:我有一个问题,我现在想在同一个文本文件中找到几个独立的部分。我如何才能创建一个循环来进一步查找“*geo”和“*house”之间的行,以及“*name”和“*姓氏”之间的行?我试图创建一个完全独立的定义,但希望尽量减少我使用的代码行…谢谢!代码我一直在使用类似的结构(如我的原始问题所提供的,多亏了mgilson!),因此我想编辑这些类型的代码

def parse_file(ff):     
    out=[]     
    append=False     
    for line in ff:         
        if(append and line.strip()):
            out.append(line)          
            if(line.startswith('*load')): 
                append=True
            elif(line.startswith('*stiffness')):  
                return [map(int,x.split()) for x in out[:-1] ] 

虽然我无法帮助您理解语法,但最好使用自调用

编写一个函数来检测所需的行并存储字节偏移量。 接下来,使该函数调用自身以查找下一行(结束操作),同时存储其偏移量,并将其与以前保存的值进行比较

现在您有足够的数据来确定需要更改哪些字节

但是,如果使用得当,自调用函数是非常有效的,它们可以提高性能并易于重用

在php中,我构建了一个类似于.net中的streamwriter的streamwriter,它以这种方式工作。 因此我知道这个理论是有效的,但是,这似乎是python


不幸的是,我对那种语言了解不够。祝你的项目好运

像这样的事情应该可以

data=[]
check=false
for i in fid:
    if line.find("*load"):
        check=true
    if check==true and not line.find("*stiffness"):
        line=split(i)
        data.append(map(lambda x: float(x), line))
    if line.find("*stiffness"):
        break

fid.close()
for i in data:
    a=i[0]
    b=i[1]
    c=i[2]
将此代码作为粗略的建议。。。(我认为异常现在已经修复,如果没有,我也不在乎……)

让我们假设您的代码“块”由标题分隔(例如,
*header
)。在每个块中存储数据最直观的方法是在列表列表中。e、 g.
[row1,row2,…]
(其中
row1=[elem1,elem2,elem3,…]
)。然后可以将块存储在字典中,以便通过
block=dictionary['headername']
访问块

这将实现您想要的功能(此版本未经测试)


请注意,如果保证数据文件中某个标题下的每一行都有相同数量的条目,则可以将变量
info
看作一个二维行,索引为
element=info[row\u number][column\u number]
——但也可以通过
row=info[row\u number]获得整行

可能是这样的:

line = filename.readline()
if line.find("*load") == 0:
    line = filename.readline()
    while line != "\n" and line != "":
        vars = line.split(" ")
vars
只是一个示例,用于存储此代码运行后的值
['2','7','200']
(因此需要将它们转换为浮点或整数)。然后,您可以将它们附加到数组中,或者根据需要重命名它们

编辑:从上面导出的工作程序

filename = open("fff.txt", 'r')
values = {}

line = filename.readline()
while line:
    while line.find("*") != 0:
        line = filename.readline()

    sectionheader = line.strip()[1:]
    values[sectionheader] = []
    line = filename.readline()
    while line != "\n" and line != "":
        vals = [float(i) for i in line.split(" ")]
        values[sectionheader].append(vals)
        line = filename.readline()

print values

这是我对您的代码所做的:

import sys
from Tkinter import *
import tkFileDialog
from tkFileDialog import askopenfile # Open dialog box


fen1 = Tk()                              # Create window
fen1.title("Optimisation")               # Window title

menu1 = Menu(fen1)

def do_open(interesting_parts=[]):
    thefile = askopenfile(filetypes=[("Text files","*.txt")], mode='r')

    data = {} # Create a dictionary to store all the data stored per part name
    part = None
    for line in thefile:
        if line.startswith("*"):
            # A * in the beginning signals a new "part"
            # And another one means the end.
            part = line[1:] # Remove the * in the beginning via slicing to get the name without it.
            if part in interesting_parts:
                data[part] = [] # Create a list inside the dictionary, so that you can add data to it later.
                # Only do this if we are interested in storing anything for this part
        elif part in interesting_parts:
            # Add an a condition to check if the part name is in the list of "parts" you are interested in having.
            line_data = get_something_from_this(part, line) # just a function that returns something based on the line and the part
            if line_data is not None: # Ignore it if it's None (just an option, as there might be newlines that you want to ignore)
                data[part].append(line_data)

    # Here, we return the dictionary to act on it.
    return data

def get_something_from_this(part, line):
    try:
        ints = [int(p) for p in line.split()]
    except ValueError:
        print "Ignoring Line", repr(line), "in", part
        return None # We don't care about this line!
    else:
        print "in", part, ints
        return ints # Store this line's data

data = do_open(["test", "egg"]) # Pass as an argument a list of the interesting "parts"

print data # this is a dictionary

# How do you access it?
print data["test"] # to get all the lines' data in a list
print data["egg"][0] # to get the first line of the data

for part, datalines in data.iterkeys():
    print part, datalines # datalines is the list of all the data, part is the dictionary's key which is the part name
    # Remember data[part] = ... <- Here part is the key.

fen1.mainloop()

更新3:大量评论:)

我认为你的
地图
遇到“*stiffness”行时会引发一个异常。还有你的
if行。find(…)
应该是
if行。find(…)=-1
@Digitalis如果你在谈论这个词,
优化
是法语中的
优化
。如果不是的话,很可能是的,因为这就是窗口的标题是啊,我在英语和法语之间转换…因此我现在对各种拼写感到困惑:)在这种情况下拼写错误是一个很有趣的词。法语确实有道理。谢谢你澄清这一点。检查我对答案的更新。每行中总是有3个数字,这是一个随机数的行数。@user20--好的,很高兴知道,但关键是你想如何存储这些数字?你想要一张单子吗?还是每行的列表?我的回答返回了每行的列表,但我不知道这是否可取。我相信每行的列表更合适,谢谢你的帮助=)@user20:对不起。我不明白。如果没有数据文件,如何获取值?您需要数据文件才能从中读取值(我想)。当然,您只需要解析它一次,然后所有值都在那里(在我的示例中,它们在变量
output
)中)。同样,在这段代码中,由于可能有多个值,我如何将“n”行数分配给值。执行输出[0]、输出[1]等已经足够了,但是如果我有输出[n],我怎么做呢?
if line.find('*load'):
不起作用。当找到“*load”时,函数返回0(如果它是行中的第一件事)。哎呀,写得太快了,错过了。已修复。错误是什么?这似乎对我来说很有效——请看我刚才添加的更完整的示例。我只使用
line.split()
而不是
line.split(“”)
(它们之间有细微的不同)。但将所有数据存储在dict中确实是实现这一目标的方法。(这也是我最后在编辑中所做的)。我也非常喜欢这种方法,但对于在哪里可以将找到的值分配给变量以及如何找到某些部分,我有点困惑。例如,如果我只是想找到*测试和*鸡蛋。@mgilson很高兴知道两者之间有区别。。。我想我应该让它更明确。@jadkik94--您可以通过尝试以下内容很快看到区别:
“这是一个有时有两个空格的字符串”。split(“”)
--Hmmm。。。所以我的多重空间保存得不是很好。。。
import sys
from Tkinter import *
import tkFileDialog
from tkFileDialog import askopenfile # Open dialog box


fen1 = Tk()                              # Create window
fen1.title("Optimisation")               # Window title

menu1 = Menu(fen1)

def do_open(interesting_parts=[]):
    thefile = askopenfile(filetypes=[("Text files","*.txt")], mode='r')

    data = {} # Create a dictionary to store all the data stored per part name
    part = None
    for line in thefile:
        if line.startswith("*"):
            # A * in the beginning signals a new "part"
            # And another one means the end.
            part = line[1:] # Remove the * in the beginning via slicing to get the name without it.
            if part in interesting_parts:
                data[part] = [] # Create a list inside the dictionary, so that you can add data to it later.
                # Only do this if we are interested in storing anything for this part
        elif part in interesting_parts:
            # Add an a condition to check if the part name is in the list of "parts" you are interested in having.
            line_data = get_something_from_this(part, line) # just a function that returns something based on the line and the part
            if line_data is not None: # Ignore it if it's None (just an option, as there might be newlines that you want to ignore)
                data[part].append(line_data)

    # Here, we return the dictionary to act on it.
    return data

def get_something_from_this(part, line):
    try:
        ints = [int(p) for p in line.split()]
    except ValueError:
        print "Ignoring Line", repr(line), "in", part
        return None # We don't care about this line!
    else:
        print "in", part, ints
        return ints # Store this line's data

data = do_open(["test", "egg"]) # Pass as an argument a list of the interesting "parts"

print data # this is a dictionary

# How do you access it?
print data["test"] # to get all the lines' data in a list
print data["egg"][0] # to get the first line of the data

for part, datalines in data.iterkeys():
    print part, datalines # datalines is the list of all the data, part is the dictionary's key which is the part name
    # Remember data[part] = ... <- Here part is the key.

fen1.mainloop()
*test
1 2 3

*load
2 7 200
3 7 150

*stiffness
2 9 8

*egg
1 2 3
2 4 6

*plant
23 45 78