我想使下面的代码更简单。
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中进行这个简单的操作。
答案 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);