Modify Strings in cell array according to pattern

I have to cell arrays A & B
A = ['C1 H2 O1 N1 S1';
[];
'C5 H2 O0 N1 S0';
'C2 H6 O0 N1 S1';
'C2 H6 O2 N1 S0';
[];
'C3 H10 O1 N1 S0';
'C6 H5 O2 N2 S1';
'C8 H9 O4 N0 S0';
[];
'C9 H13 O3 N0 S0';
'C10 H17 O2 N0 S0';
'C11 H21 O1 N0 S0';
'C12 H25 O0 N0 S0'];
and
B = ['C5H9O2+'
'C3H5O4'
'C3H7O5']
and I would like to have B in the same pattern as A so that (C* H* O* N* S*)
and deleting the +
B[1] = 'C5 H9 O2 NO S0'
kinda tried with regexprep() but didn't get anything by now.....

 采纳的回答

Let me know how this works for you.
B = {'C3H7O';'C2H7O2';'C2H7O2+';'C4H5O';'C4H5O';'C3H3O2';'';'C4H7O';'C3H5O2';'C3H7O2';'C2H5O3';...
'C2H5O3';'C2H7O3';'';'';'C4H5O2';'C4H5O2';'C4H5O2';'C4H7O2'};
I = {'C0','H0','O0','N0','S0'};
B = regexprep(B,{'\W','(?![CHONS]\d+)[CHONS]'},''); % Removes all but letter/number pairs
B(cellfun(@isempty,B)) = join(I,''); % Replaces empty cells with I
% Adds missing letter/number pairs to each cell of B and joins with no spacing
expr = {'(C\d+)','(H\d+)','(O\d+)','(N\d+)','(S\d+)'};
for i=1:size(B,1)
B(i) = join([B{i},I(cellfun(@isempty,regexp(B{i},expr)))],'');
end
% Adds a single space between letter/number pairs
B = regexprep(B,'(C\d+)(H\d+)(O\d+)(N\d+)(S\d+)','$1 $2 $3 $4 $5');

3 个评论

You're welcome.
One thing to be aware of is that if the order of CHONS matter and they are not in this order in your original B variable, then you will need to tweak this code some.
And here we are,.... I have to tweak the code,
My new B is
B = ['C9H19NO2', 'C9H20O3', 'C6H12O6', 'C11H20O2', 'C10H19NO2', 'C10H21NO2', ...
'C10H20O3', 'C11H19NO2', 'C11H18O3', 'C12H22O2', 'C11H21NO2', 'C11H20O3']
So the order has changed to CHNOS and i would like to have it in the order as before CHONS and filled up with letter/number pair to each cell of B
PS: found a problem in the first code, when in B some letter without a number was found it shouldn't be zero e.g.
'C3H7O' = C3 H7 O0 N0 S0
but instead it should be
'C3H7O' = C3 H7 O1 N0 S0
because there is one 'O'
thanks

请先登录,再进行评论。

更多回答(1 个)

I am sure that there is a much more elegant method using just regular expressions, but the following should give you what you are looking for if your input cell-array is similar to the example provided.
B = {'C5H9O2+'
'C3H5O4'
'C3H7O5'};
I = {'C','H','O','N','S'};
% Looks for 'C', 'H', 'O', 'N',and 'S' and when not present in a cell-array element, append the
% missing charater followed by a '0' to the cell-array element.
for i=1:length(I)
idx = ~contains(B,I{i});
B(idx) = append(B(idx),I{i},'0');
end
% Use regular expression to replace all non-alphanumeric or underscore characters, then find
% matching tokens consisting of 'C', 'H', 'O', 'N', and 'S' each followed by any number of digits
% and recombine them as a single space-delimited string.
regexprep(B,{'\W','(C\d*)(H\d*)(O\d*)(N\d*)(S\d*)'},{'','$1 $2 $3 $4 $5'})

3 个评论

Thanks Allen, appreciate your help! Got an error according to append();
%Error using append (line 38)
%Wrong number of input arguments for obsolete matrix-based syntax.
Tried to fix it with:
B(idx) = [B(idx); I{i}; '0']; instead of %B(idx) = append(B(idx),I{i},'0');
But regexprep gives me an error as well
% In an assignment A(:) = B, the number of elements in A and B must be the same.
Here is a bigger set of my Cell B.
B = ['C3H7O';
'C2H7O2';
'C2H7O2+'
'C4H5O';
'C4H5O';
'C3H3O2';
''; % the empty shouldn't make any trouble
'C4H7O';
'C3H5O2';
'C3H7O2';
'C2H5O3';
'C2H5O3';
'C2H7O3';
'';
'';
'C4H5O2';
'C4H5O2';
'C4H5O2';
'C4H7O2']
What version of MATLAB are you using? Also, you appear to be defining B as a non-cell-array instead of a cell-array. That might also be part of the problem.
Matlab 2017b
whos B
Name Size Bytes Class Attributes
B 177x1 21946 cell

请先登录,再进行评论。

类别

帮助中心File Exchange 中查找有关 Data Type Conversion 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by