Python读sdf/mdl坐标:如何读到两个空格?
Python read sdf/mdl coordinates: How to read until two spaces are met?
我想读取一些.sdf 文件(实际上是.mdl 文件,但当我下载它们时它们显示为.sdf),以便制作一个程序将它们转换为另一种格式。 .sdf 文件模拟分子,但这与那里无关。
我想读取坐标而忘记了债券,所以我需要从这样的文件格式中读取:
ALA
CCTOOLS-0424210918
13 12 0 0 1 0 0 0 0 0999 V2000
2.2810 26.2130 12.8040 N 0 0 0 0 0
1.1690 26.9420 13.4110 C 0 0 0 0 0
1.5390 28.3440 13.8740 C 0 0 0 0 0
2.7090 28.6470 14.1140 O 0 0 0 0 0
0.6010 26.1430 14.5740 C 0 0 0 0 0
0.5230 29.1940 13.9970 O 0 0 0 0 0
2.0330 25.2730 12.4930 H 0 0 0 0 0
3.0800 26.1840 13.4360 H 0 0 0 0 0
0.3990 27.0670 12.6130 H 0 0 0 0 0
-0.2470 26.6990 15.0370 H 0 0 0 0 0
0.3080 25.1100 14.2700 H 0 0 0 0 0
1.3840 25.8760 15.3210 H 0 0 0 0 0
0.7530 30.0690 14.2860 H 0 0 0 0 0
1 2 1 0 0 0
1 7 1 0 0 0
1 8 1 0 0 0
2 3 1 0 0 0
2 5 1 0 0 0
2 9 1 0 0 0
3 4 2 0 0 0
3 6 1 0 0 0
5 10 1 0 0 0
5 11 1 0 0 0
5 12 1 0 0 0
6 13 1 0 0 0
M END
$$$$
我想从第 3 行开始读到数字前只有 2 spaces。
如果你:
file=open('ALA_model.sdf',mode="r")
string_list=file.readlines()
file.close()
datasplit=[]
for i in range(len(string_list)):
datasplit.append(string_list[i].split(" "))
(快速提醒:ALA_model.sdf 是上面文件的名称,但不是我必须处理的唯一文件。请随意使用上面的 ALA 文件,因为我从 http://ligand-expo.rcsb.org/reports/A/ALA/ALA_model.sdf)
下载
你会发现
datasplit[3]=['', '13', '12', '', '0', '', '0', '', '1', '', '0', '', '0', '', '0', '', '0', '', '0999', 'V2000\n']
这意味着开始阅读。那么我们有:
datasplit[4]=['', '', '', '', '2.2810', '', '', '26.2130', '', '', '12.8040', 'N', '', '', '0', '', '0', '', '0', '', '0', '', '0\n']
我只需要前三个数字和 letter/atom,但我自己可以处理。
最后但同样重要的是,
datasplit[17]=['', '', '1', '', '2', '', '1', '', '0', '', '0', '', '0\n']
第一行是我不想看的
那么当列表中的前两个 str 对象是 space 字符串时,如何停止读取?
我相信在这种情况下它会来自 string_list[4:16],但我还有其他 .sdf 文件可以读取,每个文件都有不同的长度,我想从中构建一个函数,使它成为可迭代的,你知道的,无需为每个脚本制作脚本。
综上所述,在不关心格式的情况下,我们如何遍历第一个 three/four 个字符串值为 space 的列表,直到第三个字符串值为一个数字?
在你的情况下,我会逐行读取文件并检查每一行是否有四个 spaces。
string_list = []
with open('ALA_model.sdf') as file:
for line in file:
if line.startswith(' '):
string_list.append(line)
else:
# finish reading here
continue
此示例不包括跳过第一行并处理以 space 开头的第 4 行,但我认为您可以处理这个问题。
另一种选择可能是使用 file.read()
读取整个文件,并重复匹配所有以 3 个或更多空格开头后跟可选 -
和使用模式的数字的行。
^ {3,}-?\d.*(?:\r?\n {3,}-?\d.*)*
^
字符串开头
{3,}-?\d.*
匹配3个或更多空格,可选-
,一个数字和该行的其余部分
(?:\r?\n {3,}-?\d.*)*
可选择重复换行符和相同的模式
然后你可以使用 splitlines()
和 split()
每一行,将前 4 项附加到 datasplit
.
例如
import re
from pprint import pprint
file = open('ALA_model.sdf', mode="r")
content = file.read()
file.close()
match = re.search(r"^ {3,}-?\d.*(?:\r?\n {3,}-?\d.*)*", content, re.M)
datasplit = []
if match:
for line in match.group().splitlines():
datasplit.append([part for part in line.split()][:4])
pprint(datasplit)
输出
[['2.2810', '26.2130', '12.8040', 'N'],
['1.1690', '26.9420', '13.4110', 'C'],
['1.5390', '28.3440', '13.8740', 'C'],
['2.7090', '28.6470', '14.1140', 'O'],
['0.6010', '26.1430', '14.5740', 'C'],
['0.5230', '29.1940', '13.9970', 'O'],
['2.0330', '25.2730', '12.4930', 'H'],
['3.0800', '26.1840', '13.4360', 'H'],
['0.3990', '27.0670', '12.6130', 'H'],
['-0.2470', '26.6990', '15.0370', 'H'],
['0.3080', '25.1100', '14.2700', 'H'],
['1.3840', '25.8760', '15.3210', 'H'],
['0.7530', '30.0690', '14.2860', 'H']]
我想读取一些.sdf 文件(实际上是.mdl 文件,但当我下载它们时它们显示为.sdf),以便制作一个程序将它们转换为另一种格式。 .sdf 文件模拟分子,但这与那里无关。
我想读取坐标而忘记了债券,所以我需要从这样的文件格式中读取:
ALA
CCTOOLS-0424210918
13 12 0 0 1 0 0 0 0 0999 V2000
2.2810 26.2130 12.8040 N 0 0 0 0 0
1.1690 26.9420 13.4110 C 0 0 0 0 0
1.5390 28.3440 13.8740 C 0 0 0 0 0
2.7090 28.6470 14.1140 O 0 0 0 0 0
0.6010 26.1430 14.5740 C 0 0 0 0 0
0.5230 29.1940 13.9970 O 0 0 0 0 0
2.0330 25.2730 12.4930 H 0 0 0 0 0
3.0800 26.1840 13.4360 H 0 0 0 0 0
0.3990 27.0670 12.6130 H 0 0 0 0 0
-0.2470 26.6990 15.0370 H 0 0 0 0 0
0.3080 25.1100 14.2700 H 0 0 0 0 0
1.3840 25.8760 15.3210 H 0 0 0 0 0
0.7530 30.0690 14.2860 H 0 0 0 0 0
1 2 1 0 0 0
1 7 1 0 0 0
1 8 1 0 0 0
2 3 1 0 0 0
2 5 1 0 0 0
2 9 1 0 0 0
3 4 2 0 0 0
3 6 1 0 0 0
5 10 1 0 0 0
5 11 1 0 0 0
5 12 1 0 0 0
6 13 1 0 0 0
M END
$$$$
我想从第 3 行开始读到数字前只有 2 spaces。
如果你:
file=open('ALA_model.sdf',mode="r")
string_list=file.readlines()
file.close()
datasplit=[]
for i in range(len(string_list)):
datasplit.append(string_list[i].split(" "))
(快速提醒:ALA_model.sdf 是上面文件的名称,但不是我必须处理的唯一文件。请随意使用上面的 ALA 文件,因为我从 http://ligand-expo.rcsb.org/reports/A/ALA/ALA_model.sdf)
下载你会发现
datasplit[3]=['', '13', '12', '', '0', '', '0', '', '1', '', '0', '', '0', '', '0', '', '0', '', '0999', 'V2000\n']
这意味着开始阅读。那么我们有:
datasplit[4]=['', '', '', '', '2.2810', '', '', '26.2130', '', '', '12.8040', 'N', '', '', '0', '', '0', '', '0', '', '0', '', '0\n']
我只需要前三个数字和 letter/atom,但我自己可以处理。
最后但同样重要的是,
datasplit[17]=['', '', '1', '', '2', '', '1', '', '0', '', '0', '', '0\n']
第一行是我不想看的
那么当列表中的前两个 str 对象是 space 字符串时,如何停止读取? 我相信在这种情况下它会来自 string_list[4:16],但我还有其他 .sdf 文件可以读取,每个文件都有不同的长度,我想从中构建一个函数,使它成为可迭代的,你知道的,无需为每个脚本制作脚本。
综上所述,在不关心格式的情况下,我们如何遍历第一个 three/four 个字符串值为 space 的列表,直到第三个字符串值为一个数字?
在你的情况下,我会逐行读取文件并检查每一行是否有四个 spaces。
string_list = []
with open('ALA_model.sdf') as file:
for line in file:
if line.startswith(' '):
string_list.append(line)
else:
# finish reading here
continue
此示例不包括跳过第一行并处理以 space 开头的第 4 行,但我认为您可以处理这个问题。
另一种选择可能是使用 file.read()
读取整个文件,并重复匹配所有以 3 个或更多空格开头后跟可选 -
和使用模式的数字的行。
^ {3,}-?\d.*(?:\r?\n {3,}-?\d.*)*
^
字符串开头{3,}-?\d.*
匹配3个或更多空格,可选-
,一个数字和该行的其余部分(?:\r?\n {3,}-?\d.*)*
可选择重复换行符和相同的模式
然后你可以使用 splitlines()
和 split()
每一行,将前 4 项附加到 datasplit
.
例如
import re
from pprint import pprint
file = open('ALA_model.sdf', mode="r")
content = file.read()
file.close()
match = re.search(r"^ {3,}-?\d.*(?:\r?\n {3,}-?\d.*)*", content, re.M)
datasplit = []
if match:
for line in match.group().splitlines():
datasplit.append([part for part in line.split()][:4])
pprint(datasplit)
输出
[['2.2810', '26.2130', '12.8040', 'N'],
['1.1690', '26.9420', '13.4110', 'C'],
['1.5390', '28.3440', '13.8740', 'C'],
['2.7090', '28.6470', '14.1140', 'O'],
['0.6010', '26.1430', '14.5740', 'C'],
['0.5230', '29.1940', '13.9970', 'O'],
['2.0330', '25.2730', '12.4930', 'H'],
['3.0800', '26.1840', '13.4360', 'H'],
['0.3990', '27.0670', '12.6130', 'H'],
['-0.2470', '26.6990', '15.0370', 'H'],
['0.3080', '25.1100', '14.2700', 'H'],
['1.3840', '25.8760', '15.3210', 'H'],
['0.7530', '30.0690', '14.2860', 'H']]