在函数返回中寻址数组

时间:2016-08-26 19:06:27

标签: matlab

我想使下面的代码更简单。

files=dir('~/some*.txt');
numFiles=length(files);
for i = 1:numFiles
    name=files(i).name;
    name=strsplit(name,'.');
    name=name{1};
    name=strsplit(name, '_');
    name=name(2);
    name = str2num(name{1});
    disp(name);
end

我是Matlab的初学者,一般来说我会喜欢这样的东西:

name = str2num(strsplit(strsplit(files(i).name,'.')(1),'_')(2));

但是matlab不喜欢这个。

上述方法的另一个问题是,即使是像name(2)这样的东西,matlab仍然会给出单元格类型,但这可能只是我的语法问题。

示例文件名:

3000_0_100ms.txt
3000_0_5s.txt
3000_110_5s.txt
...

我想说我要选择所有以' 5s'然后我需要通过'_'拆分它们(删除扩展名后)并返回第二部分,如果是上面三个文件名,则返回0, 0, 110。 但我总体上很好奇如何在没有上面复杂代码的情况下在matlab中进行这个简单的操作。

2 个答案:

答案 0 :(得分:0)

您可以使用regexp进行正则表达式匹配,并直接在第二位获取数字。 This是我正在使用的正则表达式的解释。

>>names = regexp({files(:).name},'\d*_(\d*)_\d*m?s\.txt$','tokens')
>>names = [names{:}]; % Get names out of their cells
>>names = [names{:}]; % Break cells one more time
>> nums = str2double(names); % Convert to double to obtain numbers

答案 1 :(得分:0)

由于您的文件名遵循特定模式,因此它们是regular expression的主要候选人。虽然正则表达式一开始可能令人困惑,但它们是非常强大的工具。

考虑以下示例,该示例将所有包含前导和尾随下划线的数字拉出:

filenames = {'3000_0_100ms.txt', '3000_0_5s.txt', '3000_110_5s.txt'};
strs = regexp(filenames, '(?<=\_)(\d+)(?=\_)', 'match');
strs = [strs{:}];  % Denest one layer of cells

nums = str2double(strs);

返回:

nums =

     0     0   110

在这里使用的是所谓的lookbehind (?<=...)和lookahead (?=...)运算符。正如他们的名字所暗示的那样,他们会查看与他们所属的表达相关的各自指示,(\d+)在我们的案例中,它会查找一个或多个数字。虽然这种方法比简单的'\_(\d+)\_'表达式需要更多的步骤,但后者要求您使用MATLAB的'tokens'正则表达式运算符,这会增加另一层单元格并使我烦恼,或者使用{ {1}}运算符并在转换为数值之前从匹配中删除下划线。

方法2:

'match'

方法3:

filenames = {'3000_0_100ms.txt', '3000_0_5s.txt', '3000_110_5s.txt'};
strs = regexp(filenames, '\_(\d+)\_', 'tokens');
strs = [strs{:}];  % Denest one layer of cells
strs = [strs{:}];  % Denest another layer of cells
nums = str2double(strs);