在标题

时间:2017-08-22 09:14:09

标签: python

我目前有一个脚本从文件orderedfile.txt读取数据,该文件具有标题布局和数据布局,如下所示。我现在想要一个python脚本来搜索头文件中的参数a,b,c和精细的fft网格参数(在这种情况下为25,300,300)。

头文件的布局可能略有变化,因此我认为最好不要考虑每个的位置来解决这个问题。相反,我认为接近这个的最好方法是在标题中搜索短语“a =”,然后将此后的内容设置为等于......我无法弄清楚如何实现这一点。有没有人有任何建议?

BEGIN header

       Real Lattice(A)               Lattice parameters(A)    Cell Angles
   2.4675850   0.0000000   0.0000000     a =    2.467585  alpha =   90.000000
   0.0000000  30.0000000   0.0000000     b =   30.000000  beta  =   90.000000
   0.0000000   0.0000000  30.0000000     c =   30.000000  gamma =   90.000000

 1                            ! nspins
25   300   300                ! fine FFT grid along <a,b,c>
END header: data is "<a b c> pot" in units of Hartrees

 1     1     1            0.042580
 1     1     2            0.049331
 1     1     3            0.038605
 1     1     4            0.049181

1 个答案:

答案 0 :(得分:1)

如果您可以更改文件格式,请将其更改为更易读机的内容(例如JSON)。如果您不能并且您希望对格式进行未经注意的更改,请严格检查格式,否则您很容易误解文件。

为了严格检查这些格式,我经常以非常懒惰(但可读)的方式使用正则表达式。

import re

def parse_header(f):
    l=next(f)
    m = re.match(r'BEGIN header', l)
    assert m, l
    l=next(f)
    m = re.match(r'', l)
    assert m, l
    l=next(f)
    m = re.match(r'       Real Lattice\(A\)               Lattice parameters\(A\)    Cell Angles', l)
    assert m, l
    l=next(f)
    m = re.match(r'.*a = +(?P<a>[0-9.+-]+) +.*', l)
    assert m, l
    a = float(m.group('a'))
    l=next(f)
    m = re.match(r'.*b = +(?P<b>[0-9.+-]+) +.*', l)
    assert m, l
    b = float(m.group('b'))
    l=next(f)
    m = re.match(r'.*c = +(?P<c>[0-9.+-]+) +.*', l)
    assert m, l
    c = float(m.group('c'))
    l=next(f)
    m = re.match(r'', l)
    assert m, l
    l=next(f)
    m = re.match(r'.*nspins.*', l)
    assert m, l
    l=next(f)
    m = re.match(r'.*(?P<ffta>[0-9]+) +(?P<fftb>[0-9]+) +(?P<fftc>[0-9]+) +! fine FFT grid along <a,b,c>', l)
    assert m, l
    ffta = int(m.group('ffta'))
    fftb = int(m.group('fftb'))
    fftc = int(m.group('fftc'))
    l=next(f)
    m = re.match(r'END header: data is "<a b c> pot" in units of Hartrees', l)
    assert m, l
    l=next(f)
    return a,b,c,ffta,fftb,fftc

# prepare a test 'file'
s = '''BEGIN header

       Real Lattice(A)               Lattice parameters(A)    Cell Angles
   2.4675850   0.0000000   0.0000000     a =    2.467585  alpha =   90.000000
   0.0000000  30.0000000   0.0000000     b =   30.000000  beta  =   90.000000
   0.0000000   0.0000000  30.0000000     c =   30.000000  gamma =   90.000000

 1                            ! nspins
25   300   300                ! fine FFT grid along <a,b,c>
END header: data is "<a b c> pot" in units of Hartrees

 1     1     1            0.042580
 1     1     2            0.049331
 1     1     3            0.038605
 1     1     4            0.049181'''

# file like iterable
f=iter(s.split("\n"))


a,b,c,ffta,fftb,fftc = parse_header(f)
# continue with the file and handle remaining data lines
for line in f:
    print(line)