Replacing specfic numbers in string

2 Ansichten (letzte 30 Tage)
LukasJ
LukasJ am 17 Jun. 2020
Bearbeitet: Stephen23 am 18 Jun. 2020
Dear all,
I have got a substring and an array which look like this
substr={'B0.2Si0.05'};
numarray = [0.184320000000000 0.0460800000000000];
I want to replace the numbers in the substring (0.2, 0.5) in with the numbers from numarray. 0.2 should then become 0.18432 and 0.5 should become 0.04608 respectively. This seems pretty simply but I somehow fail to do it.
I have tried to do
newSubstr = regexprep(substr{1}, '(\d+)(?:\.(\d{1,2}))?', cellfun(@num2str, num2cell(numarray), 'uni', false));
newSubstr =
1×1 cell array
{'B0.046080.04608Si0.046080.04608'}
I also tried using cellstr, sprintfc, strrep but I didn't get what I want :( e.g.
newSubstr = regexprep(substr{1},'(\d+)(?:\.(\d{1,2}))?', sprintfc('%f', numarray))
newSubstr =
1×1 cell array
{'B0.0460800.046080Si0.0460800.046080'}
The solution has to be dynamic e.g. Substr can easily have more components and numarray will always grow with it. I'm sure that I'm missing something very basic here...
Cheers,
Lukas

Akzeptierte Antwort

Rik
Rik am 17 Jun. 2020
Apart from needing to replace the commas in your array by periods, I don't see where you went wrong. The RE seems fine and the way I read the documentation for regexprep this should work as you expected.
Since I can't fix your code, I wrote some new code that should do the same as what you intended:
substr={'B0.2Si0.05'};
numarray = [0.184320000000000 0.0460800000000000];
c=arrayfun(@(x) sprintf('%.5f',x), numarray, 'uni', false);
% or with the undocumented sprintfc:
% c=sprintfc('%.5f', numarray);
re='(\d+)(?:\.(\d{1,2}))?';
split=regexp(substr{1},re,'split');
txt=split(:)';
k=1:min(numel(c),numel(txt));
txt(2,k)=c(k);
txt(cellfun('isempty',txt))={''};
newSubstr=horzcat(txt{:});
  2 Kommentare
LukasJ
LukasJ am 17 Jun. 2020
Thanks for your answer! I‘m sorry about the ,/. mix-up and corrected it.
Your code feels kind of needlessly long tbh :D How can something that simple take so many lines?!
According to api if I feed it (str, regex, cell) it should just fill in the matches with the corresponding cell entry...
Rik
Rik am 18 Jun. 2020
I agree that the regexprep should work, but apparently it doesn't work like that.
My code is essentially the same as the code Stephen posted (mine has a small input check when creating k), so if you absolutely need the shortest code possible, feel free to use his.

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Stephen23
Stephen23 am 18 Jun. 2020
Bearbeitet: Stephen23 am 18 Jun. 2020
>> substr = {'B0.2Si0.05'};
>> numarray = [0.18432,0.04608];
For one element of the cell array substr:
>> spl = regexp(substr{1},'\d+\.?\d*','split');
>> spl(2,1:end-1) = arrayfun(@num2str,numarray,'uni',0);
>> substr{1} = sprintf('%s',spl{1:end-1})
substr =
'B0.18432Si0.04608'
Or to use undocumented sprintfc replace the second line with this (faster):
>> spl(2,1:end-1) = sprintfc('%.6f',numarray);
  4 Kommentare
Stephen23
Stephen23 am 18 Jun. 2020
Bearbeitet: Stephen23 am 18 Jun. 2020
"spl appears to be a 1x1 cell"
That probably means that nothing in the string matches the regular expression (i.e the string does not contain numbers with those formats), therefore there is nothing to split the string on, and so regexp returns the complete string unchanged.
Either:
  • you need to specify the input data so that we can help you define a regular expression to cover your actual data which may have different number formats, or
  • you need to include basic special-case handling, e.g. isscalar(spl) and branch your code based on that.
Knowing your exact input data would help us to diagnose this.
LukasJ
LukasJ am 18 Jun. 2020
I thought I used the same input with different names but just now noticed that substr was nested twice
substring{1}{1}
I am really sorry.

Melden Sie sich an, um zu kommentieren.

Produkte


Version

R2017b

Community Treasure Hunt

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

Start Hunting!

Translated by