Reading within parentheses in MATLAB

16 次查看(过去 30 天)
NP4432
NP4432 2017-4-4
评论: Jan 2017-4-5
I have a 100 x 1 cell array where each element consists of a number followed by a space followed by a number in parentheses. For example: 401 (106), 234 (113), 345 (120)...
I would like to create a new 100 x 1 cell array where each element consists of solely the number within the parentheses. That is: 106, 113, 120...
If there a way to do this in MATLAB? I was thinking about scanning each element and reading only the data after "(" and before ")", but I don't know how to go about doing it.

回答(3 个)

Stephen23
Stephen23 2017-4-4
编辑:Stephen23 2017-4-4
This is very easy with regexp:
>> C = {'401 (106)', '234 (113)', '345 (120)'};
>> D = regexp(C,'(\d+)\s+\((\d+)\)','tokens','once');
>> str2double(cell2mat(D))
ans =
401 234 345
106 113 120
  1 个评论
Guillaume
Guillaume 2017-4-4
编辑:Guillaume 2017-4-5
Or you could use this slightly less strict regex:
str2double(regexp(C, '(?<=\()[^)]*', 'match', 'once'))
matches everything after (| up to |).

请先登录,再进行评论。


Jan
Jan 2017-4-4
编辑:Jan 2017-4-4
[EDITED] The former version replied both values, but the OP NP4432 asked for the value in parenthesis only.
C = {'401 (106)', '234 (113)', '345 (120)'};
D = sscanf(sprintf('%s ', C{:}), '%*g (%g)', [1, numel(C)]).';
R = num2cell(D, 2);
As usual a run-time comparison:
C = cell(1, 100); % Test data
for k = 1:numel(C), C{k} = '401 (106)'; end
tic
for k = 1:100
D = sscanf(sprintf('%s ', C{:}), '%*g (%g)', [1, numel(C)]).';
R1 = num2cell(D, 2);
end
toc
tic
for k = 1:100
% D = regexp(C,'(\d+)\s+\((\d+)\)','tokens','once');
% R2 = str2double(cell2mat(D)); % Does not run on my old 2009a
% R2 = str2double(cat(1, D{:}));
D = str2double(regexp(C, '(?<=\()[^)]*', 'match', 'once'));
R2 = num2cell(D, 1);
end
toc
tic
for k = 1:100
R3 = cellfun(@(x) sscanf(x, '%*g (%g)'), C, ...
'Uniformoutput', false);
end
toc
R2009a/64, Win7, 2 cores of a i5 in a VM:
Elapsed time is 0.187068 seconds. % SSCANF & SPRINTF
Elapsed time is 1.337538 seconds. % REGEXP
Elapsed time is 1.207764 seconds. % CELLFUN(SSCANF)
  4 个评论
Stephen23
Stephen23 2017-4-5
"The OP wants the number inside the parenthesis only"
Sure, and this is trivial with indexing:
>> C = {'401 (106)', '234 (113)', '345 (120)'};
>> V = sscanf([C{:}],'%d (%d)');
>> V(2:2:end)
Jan
Jan 2017-4-5
@Stephen: I have the old R2009a only during the day. I assume REGEXP of modern Matlab versions is faster. Could you post the output of the speed comparison? Thanks.

请先登录,再进行评论。


Joseph Cheng
Joseph Cheng 2017-4-4
编辑:Joseph Cheng 2017-4-4
since you've got the right idea and cellfun() is troublesome and sometimes confusing, i've coded it for you here:
dumdata = {'401 (106)',' 234 (113)',' 345 (120)'};
cellfun(@(x) str2double(x(find(x=='(')+1:find(x==')')-1)),dumdata,'Uniformoutput',false)
cellfun applies the function for each cell of the supplied cell array. otherwise this can be done in a for loop with implementing the what is shown in the anonymous function.
  2 个评论
Jan
Jan 2017-4-4
@Joseph: I get the error:
??? Index exceeds matrix dimensions.
Error in ==> @(x)str2double(x(find(x=='(')+1:find(x==')')+1))
Joseph Cheng
Joseph Cheng 2017-4-4
oopse. that should be -1, clipboard didn't update i guess when i pasted in my script.

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Logical 的更多信息

标签

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by