我目前有一个脚本从文件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
答案 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)