我经常使用Python解析格式化的文本文件(用于生物学研究,但我会尝试以一种你不需要生物学背景的方式提问我。)我处理一种文件 - 称为pdb文件 - 包含格式化文本中蛋白质的3D结构。这是一个例子:
HEADER CHROMOSOMAL PROTEIN 02-JAN-87 1UBQ
TITLE STRUCTURE OF UBIQUITIN REFINED AT 1.8 ANGSTROMS RESOLUTION
REMARK 1
REMARK 1 REFERENCE 1
REMARK 1 AUTH S.VIJAY-KUMAR,C.E.BUGG,K.D.WILKINSON,R.D.VIERSTRA,
REMARK 1 AUTH 2 P.M.HATFIELD,W.J.COOK
REMARK 1 TITL COMPARISON OF THE THREE-DIMENSIONAL STRUCTURES OF HUMAN,
REMARK 1 TITL 2 YEAST, AND OAT UBIQUITIN
REMARK 1 REF J.BIOL.CHEM. V. 262 6396 1987
REMARK 1 REFN ISSN 0021-9258
ATOM 1 N MET A 1 27.340 24.430 2.614 1.00 9.67 N
ATOM 2 CA MET A 1 26.266 25.413 2.842 1.00 10.38 C
ATOM 3 C MET A 1 26.913 26.639 3.531 1.00 9.62 C
ATOM 4 O MET A 1 27.886 26.463 4.263 1.00 9.62 O
ATOM 5 CB MET A 1 25.112 24.880 3.649 1.00 13.77 C
ATOM 6 CG MET A 1 25.353 24.860 5.134 1.00 16.29 C
ATOM 7 SD MET A 1 23.930 23.959 5.904 1.00 17.17 S
ATOM 8 CE MET A 1 24.447 23.984 7.620 1.00 16.11 C
ATOM 9 N GLN A 2 26.335 27.770 3.258 1.00 9.27 N
ATOM 10 CA GLN A 2 26.850 29.021 3.898 1.00 9.07 C
ATOM 11 C GLN A 2 26.100 29.253 5.202 1.00 8.72 C
ATOM 12 O GLN A 2 24.865 29.024 5.330 1.00 8.22 O
ATOM 13 CB GLN A 2 26.733 30.148 2.905 1.00 14.46 C
ATOM 14 CG GLN A 2 26.882 31.546 3.409 1.00 17.01 C
ATOM 15 CD GLN A 2 26.786 32.562 2.270 1.00 20.10 C
ATOM 16 OE1 GLN A 2 27.783 33.160 1.870 1.00 21.89 O
ATOM 17 NE2 GLN A 2 25.562 32.733 1.806 1.00 19.49 N
ATOM 18 N ILE A 3 26.849 29.656 6.217 1.00 5.87 N
ATOM 19 CA ILE A 3 26.235 30.058 7.497 1.00 5.07 C
ATOM 20 C ILE A 3 26.882 31.428 7.862 1.00 4.01 C
ATOM 21 O ILE A 3 27.906 31.711 7.264 1.00 4.61 O
ATOM 22 CB ILE A 3 26.344 29.050 8.645 1.00 6.55 C
ATOM 23 CG1 ILE A 3 27.810 28.748 8.999 1.00 4.72 C
ATOM 24 CG2 ILE A 3 25.491 27.771 8.287 1.00 5.58 C
ATOM 25 CD1 ILE A 3 27.967 28.087 10.417 1.00 10.83 C
TER 26 ILE A 3
HETATM 604 O HOH A 77 45.747 30.081 19.708 1.00 12.43 O
HETATM 605 O HOH A 78 19.168 31.868 17.050 1.00 12.65 O
HETATM 606 O HOH A 79 32.010 38.387 19.636 1.00 12.83 O
HETATM 607 O HOH A 80 42.084 27.361 21.953 1.00 22.27 O
END
ATOM
标记包含原子坐标的线的开头。 TER
标记坐标的结尾。我想采用包含原子坐标的整个文本块,所以我使用:
import re
f = open('example.pdb', 'r+')
content = f.read()
coor = re.search('ATOM.*TER', content) #take everthing between ATOM and TER
但它什么都不匹配。必须有一种方法可以使用正则表达式来获取整个文本块。我也不明白为什么这个正则表达式模式不起作用。感谢帮助。
答案 0 :(得分:3)
这应该匹配(但我还没有实际测试过):
coor = re.search('ATOM.*TER', content, re.DOTALL)
如果您阅读documentation on DOTALL
,就会理解为什么它不起作用。
编写上述内容的更好方法是
coor = re.search(r'^ATOM.*^TER', content, re.MULTILINE | re.DOTALL)
要求ATOM
和TER
位于换行符之后,并且raw string notation正在使用,这是正则表达式的惯例(尽管它不会成功在这种情况下的差异)。
你也可以完全避免使用正则表达式:
start = content.index('\nATOM')
end = content.index('\nTER', start)
coor = content[start:end]
(这实际上不包括结果中的TER
,这可能更好。)
答案 1 :(得分:1)
您需要(?s)
修饰符:
import re
f = open('example.pdb', 'w+')
content = f.read()
coor = re.search('(?s)ATOM.*TER', content)
print coor;
这会将所有内容(包括换行符)与.*
匹配。
请注意,如果您只需要介于两者之间的任何内容(ATOM
包含,TER
独占),只需更改为TER
的正面预测:
'(?s)ATOM.*(?=TER)'
答案 2 :(得分:1)
import re
pattern=re.compile(r"ATOM(.*?)TER")
print pattern.findall(string)
这应该这样做。
答案 3 :(得分:1)
非正则表达式替代方案怎么样?它可以通过一个相对简单的循环和一点点状态来实现。例如:
# Gather all sets of ATOM-TER in all_coors (if there are multiple per file).
all_coors = []
f = open('example.pdb', 'w+')
coor = None
in_atom = False
for line in f:
if not in_atom and line.startswith('ATOM'):
# Found first ATOM, start collecting results.
in_atom = True
coor = []
elif in_atom and line.startswith('TER'):
# Found TER, stop collecting results.
in_atom = False
# Save collected results.
all_coors.append(''.join(coor))
coor = None
if in_atom:
# Collect ATOM result.
coor.append(line)
答案 4 :(得分:1)
我不会使用正则表达式,而是使用itertool的dropwhile
和takewhile
,这比将整个文件加载到内存中以执行正则表达式操作更有效。 (例如,我们只是在ATOM之前忽略文件的开头,然后在遇到TER后我们不需要再从文件中读取)。
from itertools import dropwhile, takewhile
with open('example.pdb') as fin:
until_atom = dropwhile(lambda L: not L.startswith('ATOM'), fin)
atoms = takewhile(lambda L: L.startswith('ATOM'), until_atom)
for atom in atoms:
print atom,
因此,当它们不以ATOM开始时忽略行,然后在它们仍以ATOM开始时继续从该点开始行。如果需要,您可以将该条件更改为lambda L: not L.startswith('TER')
。
您可以使用:
而不是打印all_atom_text = ''.join(atoms)
获取一个大文本块。