MATLAB: Skill with regexprep

MATLABperlregexp

I am new to MATLAB but have years of experience in Perl.
Can anyone offer suggestions as to how to improve the following MATLAB code?
Although what I have works, are there better ways to loop over the record to get closer to the one-line construction of Perl?
My thanks, in advance, for advice and tutorials!
The requirement is to replace all occurrences of a repeat construction "N*Value" with N repeats of the Value. This is part of the import routine for existing data files.
A Perl construction can do this in a single line. In Perl: s!(\d+)\*(\S+)!"$2 " x $1!ge;
An example data record:
DXV
30*60 30*40 30*20 30*10 30*5
3 2 1 0.5 0.3 0.15 0.08 0.04 0.02 5*0.02 0.02 0.04 0.08 0.15 0.3 0.5 1 2 3 10*5
3 2 1 0.5 0.3 0.15 0.08 0.04 0.02 5*0.02 0.02 0.04 0.08 0.15 0.3 0.5 1 2 3 10*5
3 2 1 0.5 0.3 0.15 0.08 0.04 0.02 5*0.02 0.02 0.04 0.08 0.15 0.3 0.5 1 2 3 10*5
3 2 1 0.5 0.3 0.15 0.08 0.04 0.02 5*0.02 0.02 0.04 0.08 0.15 0.3 0.5 1 2 3 10*5
3 2 1 0.5 0.3 0.15 0.08 0.04 0.02 5*0.02 0.02 0.04 0.08 0.15 0.3 0.5 1 2 3 10*5
3 2 1 0.5 0.3 0.15 0.08 0.04 0.02 5*0.02 0.02 0.04 0.08 0.15 0.3 0.5 1 2 3 10*5
3 2 1 0.5 0.3 0.15 0.08 0.04 0.02 5*0.02 0.02 0.04 0.08 0.15 0.3 0.5 1 2 3 10*5
3 2 1 0.5 0.3 0.15 0.08 0.04 0.02 5*0.02 0.02 0.04 0.08 0.15 0.3 0.5 1 2 3 10*5
3 2 1 0.5 0.3 0.15 0.08 0.04 0.02 5*0.02 0.02 0.04 0.08 0.15 0.3 0.5 1 2 3 10*5
3 2 1 0.5 0.3 0.15 0.08 0.04 0.02 5*0.02 0.02 0.04 0.08 0.15 0.3 0.5 1 2 3
30*5 30*10 30*20 30*40 30*60
/
My current code in MATLAB works OK, but is much clumsier:
record=join(file);
[startIndex,endIndex]=regexp(record,'(\d+)\*(\S+)');
if(~isempty(startIndex))
for n=numel(startIndex):-1:1
tokenNames=regexp(extractBetween(record,startIndex(n),endIndex(n)),'(?<count>\d+)\*(?<value>\S+)','names');
x_record=strings(str2double(tokenNames.count),1);
x_record(:)=tokenNames.value;
record=replaceBetween(record,startIndex(n),endIndex(n),join(x_record));
end
end

Best Answer

This should get you started:
>> str = '5*0.02 0.02 0.04 0.08 0.15 0.3 0.5 1 2 3 30*5 30*10 30*20 30*40 30*60';
>> fun = @(n,c)repmat(sprintf(' %s',c),1,str2double(n)); % or JOIN rather than SPRINTF.
>> str = regexprep(str,'\s*(\d+)\*(\S+)','${fun($1,$2)}')
str =
0.02 0.02 0.02 0.02 0.02 0.02 0.04 0.08 0.15 0.3 0.5 1 2 3 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60 60
If you use join then you can get rid of the leading \s*.