MATLAB中解析文件的最简单方法
我试图用MATLAB从文本文件中提取轮廓点。包含这些等高线点的直线示例如下:MATLAB中解析文件的最简单方法,matlab,text-parsing,Matlab,Text Parsing,我试图用MATLAB从文本文件中提取轮廓点。包含这些等高线点的直线示例如下: Cnt-0-Pt 0/0/146/171/5/146.912065/171.618881/5.500000/0 请注意,并非每一条线都以字符串Cnt-0-Pt开头(因为这些文件中除了轮廓点之外还有其他字段),但每一条轮廓点线的字段字符串中始终有一个0,也就是说,例如,不存在轮廓点线以Cnt-1-Pt开头的选项。在该字符串之后,有一个空格和两个选项卡。我想提取第二个/分隔符后面的三个整数。在本例中,它们分
Cnt-0-Pt 0/0/146/171/5/146.912065/171.618881/5.500000/0
请注意,并非每一条线都以字符串Cnt-0-Pt开头(因为这些文件中除了轮廓点之外还有其他字段),但每一条轮廓点线的字段字符串中始终有一个0,也就是说,例如,不存在轮廓点线以Cnt-1-Pt开头的选项。在该字符串之后,有一个空格和两个选项卡。我想提取第二个/分隔符后面的三个整数。在本例中,它们分别为146、171和5。最直接的方法是什么
下面是一个文本文件的示例
#
# Direction U
#
U-Number 92
U-Scale 1.470000
#
# Direction V
#
V-Number 204
V-Scale 1.470000
#
# Direction W
#
W-Number 16
W-Scale 1.470000
s-base-plane 0
#
# Video/Recorder Parameters
#
play-mode toggle
rotate-mode ObjAxis
d-xrotate 0.000
d-yrotate 0.000
d-zrotate 0.000
#
# Cut-Oblique Parameters
#
Plane-size 1.470
Plane-2D off
Plane-3D off
#
# ValidVol Parameters
#
validity-field ignored
#
# Histogram Parameters
#
histo-scale 1.000000
#
# VOI Parameters
#
Margin-Mode 2
#
# VOI Segmentations
#
Slice-Dist-U 0.562500
Slice-Dist-V 0.562500
Slice-Dist-W 3.000000
MVol_Volume 0
#Contour 0 Parameter
Contour-Start 0
Cnt-0-Contour-name Prostate
Cnt-0-Contour-color-list 16711680
Cnt-0-Contour-color 16711680
Cnt-0-Contour-Type 0
Cnt-0-Contour-Class 0
Cnt-0-Contour-Mandatory 1
Cnt-0-Contour-num 19
Cnt-0-Inter-Contour-color 12517376
Cnt-0-Segmentation_U No
Cnt-0-Segmentation_V No
Cnt-0-Segmentation_W Yes
Cnt-0-Cnt 919.658969/118.184765/919.658969/118.184765/5
Cnt-0-Pt 0/0/146/171/5/146.912065/171.618881/5.500000/0
Cnt-0-Pt 0/0/148/154/5/148.514670/154.791536/5.500000/0
Cnt-0-Pt 0/0/153/146/5/153.055382/146.511414/5.500000/0
Cnt-0-Pt 0/0/165/139/5/165.876216/139.299695/5.500000/0
Cnt-0-Pt 0/0/178/140/5/178.429949/140.635199/5.500000/0
Cnt-0-Pt 0/0/188/143/5/188.045574/143.306206/5.500000/0
Cnt-0-Pt 0/0/195/152/5/195.524394/152.921831/5.500000/0
Cnt-0-Pt 0/0/203/164/5/203.804516/164.140061/5.500000/0
Cnt-0-Pt 0/0/206/178/5/206.475523/178.563499/5.500000/0
Cnt-0-Pt 0/0/206/191/5/206.475523/191.384333/5.500000/0
Cnt-0-Pt 0/0/204/201/5/204.338717/201.267059/5.500000/0
Cnt-0-Pt 0/0/199/208/5/199.530904/208.745879/5.500000/0
Cnt-0-Pt 0/0/193/213/5/193.387588/213.553691/5.500000/0
Cnt-0-Pt 0/0/186/213/5/186.175869/213.820792/5.500000/0
Cnt-0-Pt 0/0/180/206/5/180.833855/206.876174/5.500000/0
Cnt-0-Pt 0/0/176/198/5/176.026042/198.061851/5.500000/0
Cnt-0-Pt 0/0/169/189/5/169.348525/189.514628/5.500000/0
Cnt-0-Pt 0/0/162/182/5/162.671007/182.570010/5.500000/0
Cnt-0-Pt 0/0/152/177/5/152.254080/177.495096/5.500000/0
Cnt-0-Cnt 1210.414404/141.990846/1210.414404/141.990846/6
Cnt-0-Pt 0/0/173/139/6/173.622136/139.833897/6.500000/0
Cnt-0-Pt 0/0/181/131/6/181.368056/131.286674/6.500000/0
Cnt-0-Pt 0/0/197/129/6/197.126998/129.951171/6.500000/0
Cnt-0-Pt 0/0/207/142/6/207.009724/142.772005/6.500000/0
Cnt-0-Pt 0/0/214/153/6/214.221443/153.990234/6.500000/0
问题是,您实际上有一个非平凡的、可变的行标题和不同的元素与您感兴趣的数据混合在一起。通常,像这样的文件需要逐行解析(文件格式可能应该使用XML结构),但也可以使用fast 第一步是在文件中找到
'Cnt-0-Pt'
行开始的点。下面的代码每次使用一行,直到找到'Cnt-0-Cnt'
行。然后使用textscan
读取文件的其余部分,并将相关的三列保存到单元格数组中
fid = fopen('test.txt');
while ~strncmp(fgetl(fid),'Cnt-0-Cnt',9)
end
C = textscan(fid,'%*s%*f/%*f/%f/%f/%f/%*s','CommentStyle','Cnt-0-Cnt')
fclose(fid);
textscan
格式字符串,'%*s%*f/%*f/%f/%f/%s'
忽略第一个字符串、前两个数字以及您感兴趣的三个数字之后的所有内容。'CommentStyle'
被用作一种技巧,用来忽略以'Cnt-0-Cnt'
开头的任何后续行。有关更完整的详细信息,请参阅textscan
文档。通过将所有字段名添加到'CommentStyle'
单元格数组,例如,{'#'、'U-Number'、'U-Scale'、'V-Number'、…}
可以避免while循环,这是@horcler答案的一个不太聪明、稍微更明确的版本:
fID = fopen('test.txt', 'r');
ii = 1;
mydata = [];
while ~feof(fID) % Loop until we've reached the end of the file
tline = fgetl(fID);
if ~isempty(regexp(tline, 'Cnt-0-Pt', 'Once'))
% Matched the line we want, parse it
splitline = regexp(tline, '/', 'split'); % Split along the / delimiter
tdata = cellfun(@str2double, splitline(3:5), 'UniformOutput', false); % Convert the strings you want to doubles
mydata(ii,:) = [tdata{:}]; % Pull data out of the cell array
ii = ii + 1;
end
end
fclose(fID);
这会一行一行地遍历文件,直到到达末尾。如果它找到您的Cnt-0-Pt
字符串,它将解析该行中的数据,否则该行将被丢弃
这可能是一种计算量非常大的方法,因为它没有发挥MATLAB的任何优势。由于数据的大小和布局是可变的,因此您不能预先分配或告诉MATLAB在文件中具体读取的位置。尽管在这种情况下,逐行方法可能是唯一的好选择。请提供一个关于此文件外观的最小但完整的示例。什么是“字段字符串”?“不是每行”我只看到一行。对不起,我应该举一个完整的例子。现在,第一个'Cnt-0-Pt'
上面的部分总是有相同的行数,还是有所不同?在'Cnt-0-Cnt'
行开始之前,是否总是有一行'Cnt-0-Pt'
行?效果很好。非常感谢你的帮助!