hylovegj 发表于 2010-11-8 16:09:51

如何读取数值和字符混合型文本文件中的数值型数据(正则表达式)[有代码]

本帖最后由 messenger 于 2010-11-12 19:43 编辑

data.in文本文件包含以下信息:
a
b
c
0 1 2 3 0 0
   1 2 3 0 0 →注意本行开头是两个空格!
0 4 5 6 0 0
d
e
0 7 8 9 0 0
   7 8 9 0 0 →注意本行开头是两个空格!
0 10 11 12 0
请问如何将其中的非零数值型数据写入data.out文本文件?
我要的结果是data.out文件只包含下面的数据:
1 2 3
1 2 3
4 5 6
7 8 9
7 8 9
10 11 12
请各位朋友积极建言献策。小弟在此先行谢过!

lin2009 发表于 2010-11-8 16:34:34

用正则表达式函数regexp()把每一行的非零数值提取出来。

feynmand 发表于 2010-11-8 19:49:23

看你的输入数据结构是不是很规范了,如果是你写出的这样,那么可以将每行前两个字符去掉,然后取剩余的前三个数字就可以了。

hylovegj 发表于 2010-11-8 19:51:58

本帖最后由 hylovegj 于 2010-11-8 19:53 编辑

用正则表达式函数regexp()把每一行的非零数值提取出来。
lin2009 发表于 2010-11-8 16:34 http://forum.simwe.com/images/common/back.gif
“lin2009”兄,能否麻烦您说想详细一点?最好写个m文件把具体操作方法贴出来。

hylovegj 发表于 2010-11-8 21:32:14

看你的输入数据结构是不是很规范了,如果是你写出的这样,那么可以将每行前两个字符去掉,然后取剩余的前三个数字就可以了。
feynmand 发表于 2010-11-8 19:49 http://forum.simwe.com/images/common/back.gif
这个是FEA软件分析产生的结果文件,格式是一样的,数据被我简化了。我要用for循环不断修改里面的这些数值型数据,调用FEA软件分析,所以根本不可能手动去掉前面的空格。等待更完善的做法。。。

zhouyang664 发表于 2010-11-8 21:47:43

对于你的数据,只需用fgets读进来一行,将前两个字符去掉,然后只读取3个数字不就可以了吗?
仅仅提供一种思路...

xuxu1457 发表于 2010-11-9 12:46:27

就用fgets或者fgetl读取一行 然后选取就行 以前用这个做过ABAQUS的inp文件的转换

qibbxxt 发表于 2010-11-9 14:38:14

clear;clc;close all
fid=fopen('data.in');
fid1=fopen('data.out','w');
while ~feof(fid)
    tline = fgetl(fid);
    str=textscan(tline,'%s','delimiter',' ');
    strd=str2double(str{:});
    if all(isnan(strd))
      continue;
    else
      data=nonzeros(strd(~isnan(strd)));
      fprintf(fid1,'%d ',data');
    end
    fprintf(fid1,'\n');
end
fclose(fid);
fclose(fid1);
dbtype data.out
1   1 2 3
2   1 2 3
3   4 5 6
4   7 8 9
5   7 8 9
6   10 11 12
注:本程序只适用于此种形式的数据,如果文件中的数据有变,就灵活调整程序

bainhome 发表于 2010-11-10 13:50:38

感觉continue可以不用,把else的那部分提到前面,else部分可不写,也可用disp或者error之类写个提示什么的。

hylovegj 发表于 2010-11-11 01:35:00

本帖最后由 hylovegj 于 2010-11-11 01:37 编辑

特别感谢qibbxxt 版主关于如何跳过非数值行的思路。我要处理的数据比我在帖子里举的要复杂,但在qibbxxt 版主的启发下问题已得到解决。我会贴出原问题和我的初步解答方法,请大家帮我改进。感谢大家的帮助!

lin2009 发表于 2010-11-12 19:11:18

感觉应该不会像8#那样复杂,就重新看了一下Matlab的正则表达式。
发现这样的问题用正则表达式处理很简单。
程序和说明(注释)如下:
data.in文本文件包含以下信息:
a
b
c
0 1 2 3 0 0
   1 2 3 0 0 →注意本行开头是两个空格!
0 4 5 6 0 0
d
e
0 7 8 9 0 0
   7 8 9 0 0 →注意本行开头是两个空格!
0 10 11 12 0
请问如何将其中的非零数值型数据写入data.out文本文件?
objstr = fileread('data.in'); % 将整个文件文本以字符串形式读取,赋给变量。
pat = '((\d*)\s+){2}(\d*)';% 正则表达式模式,读取三个以空格分开的整数。
m = regexp(objstr,pat,'match');   % 行模式
fid = fopen('data.out','w');
fprintf(fid, '%s\n', m{:});                  % 不用循环,直接写入目标文件
fclose(fid);
data.out文件即为1#所需。

rocwoods 发表于 2010-11-12 20:06:53

正则表达式的介绍MATLAB帮助文档说得很详细,而且正则表达式运用好了,很多时候也非常给力。不想看英文的同学可以看看WaitingForMe和sogooda的这两个帖子:
http://forum.simwe.com/thread-469324-1-1.html
http://forum.simwe.com/viewthread.php?tid=810764

aliuhj 发表于 2010-11-13 08:50:53

这个帖子的回帖阵容可谓空前强大啊!三个版主,一个VIP会员,一个五级会员,而且还那么多高水准代码,够给力!要是论坛里的每个问题贴都可以这么火爆,得到这么多高人的关注,仿真论坛的学术氛围一定会越来越浓厚的。

knightman 发表于 2010-11-14 18:39:21

都是高人。 学习了,尽管我很多都看不懂。

hylovegj 发表于 2010-11-24 17:48:45

我自己写了一段很菜的代码,方法很笨,但思路很清晰,对不会正则表达式的朋友也是一种可以考虑的选择。下面是代码,大家可以帮我改进一下。
fid_in = fopen('data.in');
fid_out = fopen('data.out','w');
i = 0;
while ~feof(fid_in) % 判断文件指针是否达到文件末尾
    tline = fgetl(fid_in); % 将文件指针所在的行作为一个字符串整体读入
    if isnan(str2double(strread(tline,'%s%*[^\n]')))
      continue;% 跳过以字母开头的行
    else
      i = i + 1;% i用于统计数据行,并作为存储所读取数据的数组元素的下标
      if strncmp(tline,'0',1)
            =strread(tline,'%*d%d%d%d%*[^\n]');
            % 读取以0开头的数据行中的非零数据
      else
            =strread(tline,'%d%d%d%*[^\n]');
            % 读取不是以0开头的数据行中的非零数据
      end
    end
    fprintf(fid_out,'%d%d%d\n',a(i),b(i),c(i));
    % 将所读取的数据写入data.out文件
end
fclose(fid_in);
fclose(fid_out);
页: [1]
查看完整版本: 如何读取数值和字符混合型文本文件中的数值型数据(正则表达式)[有代码]