Matlab: Split string into multiple strings at the points where '_' exists - string

I have a string which is this:
a = 'Sound_impro_Act'
I want to divide this into multiple strings which are the words that are seperated by '_' and assign these to different variables.
The end result will be like this:
b = 'Sound'
c = 'impro'
d = 'act'
Thanks.

You may also use regexp which is faster than strsplit
a = 'Sound_impro_Act';
parts = regexp(a,'_','split');
[b,c,d] = deal(parts{:});
The last line comes from #Divakar's answer. Lots of thanks!

Use strsplit and then deal to put them into different variables -
split_strings = strsplit(a,'_')
[b,c,d] = deal(split_strings{:})

strsplit function can do it for you:
An example:
a = 'Sound_impro_Act';
b= strsplit(a, '_');
now you can access all splited values using b(1), b(2), b(3)

Related

sort string according to first characters matlab

I have an cell array composed by several strings
names = {'2name_19surn', '3name_2surn', '1name_2surn', '10name_1surn'}
and I would like to sort them according to the prefixnumber.
I tried
[~,index] = sortrows(names.');
sorted_names = names(index);
but I get
sorted_names = {'10name_1surn', '1name_2surn', '2name_19surn', '3name_2surn'}
instead of the desired
sorted_names = {'1name_2surn', '2name_19surn', '3name_2surn','10name_1surn'}
any suggestion?
Simple approach using regular expressions:
r = regexp(names,'^\d+','match'); %// get prefixes
[~, ind] = sort(cellfun(#(c) str2num(c{1}), r)); %// convert to numbers and sort
sorted_names = names(ind); %// use index to build result
As long as speed is not a concern you can loop through all strings and save the first digets in an array. Subsequently sort the array as usual...
names = {'2name_2', '3name', '1name', '10name'}
number_in_string = zeros(1,length(names));
% Read numbers from the strings
for ii = 1:length(names)
number_in_string(ii) = sscanf(names{ii}, '%i');
end
% Sort names using number_in_string
[sorted, idx] = sort(number_in_string)
sorted_names = names(idx)
Take the file sort_nat from here
Then
names = {'2name', '3name', '1name', '10name'}
sort_nat(names)
returns
sorted_names = {'1name', '2name', '3name','10name'}
You can deal with arbitrary patterns using a regular expression:
names = {'2name', '3name', '1name', '10name'}
match = regexpi(names,'(?<number>\d+)\D+','names'); % created with regex editor on rubular.com
match = cell2mat(match); % cell array to struct array
clear numbersStr
[numbersStr{1:length(match)}] = match.number; % cell array with number strings
numbers = str2double(numbersStr); % vector of numbers
[B,I] = sort(numbers); % sorted vector of numbers (B) and the indices (I)
clear namesSorted
[namesSorted{1:length(names)}] = names{I} % cell array with sorted name strings

meshgrid equivalent for strings

I have two cells:
Months1 = {'F','G','H','J','K','M','N','Q','U','V','X','Z'};
Months2 = 2009:2014;
How do I generate all combinations without running a loop so that I achieve the following:
Combined = {'F09','F10','F11','',...,'G09',.....};
Basically all combinations of Months1 and Months2 as in meshgrid.
If you don't need cells and can use char arrays only, this can work:
Months1 = ['F','G','H','J','K','M','N','Q','U','V','X','Z']';
Months2 = num2str((2009:2014)');
[x, y] = meshgrid(1:12, 1:6);
Combined = strcat(Months1(x(:)), Months2(y(:),:));
and you can then reshape if required. I'm not yet sure how to do this with cells, though.
Inspired by this post.
My take on the problem would apply ndgrid, datestr (to handle any millennium) and strcat to do the work:
yearStrings = datestr(datenum(num2str(Months2(:)),'yyyy'),'yy');
[ii,jj] = ndgrid(1:numel(Months2),1:numel(Months1));
Combined = strcat(Months1(jj(:)).',yearStrings(ii(:),:)).'
Note: Years change faster than the prefixed letters, so Months2 goes first in ndgrid, then Months1. IMO, this is more intuitive behavior than meshgrid, which forces you to think in x,y space to predict how the outputs vary.
Or instead of the strcat line:
tmp = [Months1(jj(:)).',yearStrings(ii(:),:)].';
Combined = cellstr(reshape([tmp{:}],[],numel(ii)).').'
You can convert cell array to indices with grp2idx, then use meshgrid, then strcat to combine strings. Before you also need to convert numeric Months2 vector to cell array of strings.
[id1,id2] = meshgrid(grp2idx(Months1),Months2);
Months2cell = cellstr(num2str(id2(:)-2000,'%02d'))';
Combined = strcat( Months1(id1(:)), Months2cell );

Lua - gmatch scientific notation string to number

I am trying to convert a string of scientific notation numbers into actual numbers.
My test string is formatted like so:
myString = 1.000000000000000E+00, 2.000000000000000E+02, -1.000000000000000E+05
My current code:
elements = {}
for s in myString:gmatch('%d+%.?%d*') do
table.insert(elements, s);
end
return unpack(elements);
Elements returns the following incorrectly:
1.000000000000000 %from the first number before "E"
00 %after the "E" in the first number
2.000000000000000 %from the second number before "E"
Anyone know how I can go about fixing this?
To me, "actual numbers" means the number data type. tonumber() does quite well with scientific notation.
local myString = [[ 1.000000000000000E+00,
2.000000000000000E+02, -1.000000000000000E+05 ]]
local function convert(csv)
local list = {}
for value in (csv .. ","):gmatch("(%S+)%W*,") do table.insert(list,tonumber(value)) end
return unpack(list)
end
print(convert(myString))
Try this instead:
for s in (myString..","):gmatch("(%S+),") do print(s) end
I would suggest using the gsplit function defined here: SplitJoin, and then having a loop like so:
t = {}
for number in gsplit(myString:gsub('%s',''),',') do
t[#t+1] = tonumber(number)
end
Which for a string:
myString = [[1.000000000000000E+00, 2.000000000000000E+02, -1.000000000000000E+05]]
the result of table.concat(t,',') is:
1,200,-100000
Here is another answer, which is robust but probably overkill:
f = loadstring("return {" .. myString .."}")
if f==nil then end -- myString malformed
elements = f()
Extend the pattern to recognize optional mantissa and use tonumber to get the number from the string:
elements = {}
myString = "1.000000000000000E+00, 2.000000000000000E+02, -1.000000000000000E+05"
for s in myString:gmatch('[+%-]?%d+%.?%d*[eE+%-]*%d?%d?') do
table.insert(elements, tonumber(s))
end
print(unpack(elements))

Is it possible to concatenate a string with series of number?

I have a string (eg. 'STA') and I want to make a cell array that will be a concatenation of my sting with a numbers from 1 to X.
I want the code to do something like the fore loop here below:
for i = 1:Num
a = [{a} {strcat('STA',num2str(i))}]
end
I want the end results to be in the form of {<1xNum cell>}
a = 'STA1' 'STA2' 'STA3' ...
(I want to set this to a uitable in the ColumnFormat array)
ColumnFormat = {{a},... % 1
'numeric',... % 2
'numeric'}; % 3
I'm not sure about starting with STA1, but this should get you a list that starts with STA (from which I guess you could remove the first entry).
N = 5;
[X{1:N+1}] = deal('STA');
a = genvarname(X);
a = a(2:end);
You can do it with combination of NUM2STR (converts numbers to strings), CELLSTR (converts strings to cell array), STRTRIM (removes extra spaces)and STRCAT (combines with another string) functions.
You need (:) to make sure the numeric vector is column.
x = 1:Num;
a = strcat( 'STA', strtrim( cellstr( num2str(x(:)) ) ) );
As an alternative for matrix with more dimensions I have this helper function:
function c = num2cellstr(xx, varargin)
%Converts matrix of numeric data to cell array of strings
c = cellfun(#(x) num2str(x,varargin{:}), num2cell(xx), 'UniformOutput', false);
Try this:
N = 10;
a = cell(1,N);
for i = 1:N
a(i) = {['STA',num2str(i)]};
end

How can I concatenate strings in a cell array with spaces between them in MATLAB?

I want to concatenate (padding with spaces) the strings in a cell array {'a', 'b'} to give a single string 'a b'. How can I do this in MATLAB?
You can cheat a bit, by using the cell array as a set of argument to the sprintf function, then cleaning up the extra spaces with strtrim:
strs = {'a', 'b', 'c'};
strs_spaces = sprintf('%s ' ,strs{:});
trimmed = strtrim(strs_spaces);
Dirty, but I like it...
matlab have a function to do this,
ref:
strjoin
http://www.mathworks.com/help/matlab/ref/strjoin.html
strjoin
Join strings in cell array into single string
Syntax
str = strjoin(C) example
str = strjoin(C,delimiter)
Ex:
Join List of Words with Whitespace
Join individual strings in a cell array of strings, C, with a single space.
C = {'one','two','three'};
str = strjoin(C)
str =
one two three
Small improvement (?) on the answer by Alex
strs = {'a','b','c'};
strs_spaces = [strs{1} sprintf(' %s', strs{2:end})];
You can accomplish this using the function STRCAT to append blanks to all but the last cell of your cell array and then concatenate all the strings together:
>> strCell = {'a' 'b' 'c' 'd' 'e'};
>> nCells = numel(strCell);
>> strCell(1:nCells-1) = strcat(strCell(1:nCells-1),{' '});
>> fullString = [strCell{:}]
fullString =
a b c d e
Both join and strjoin are introduced in R2013a. However, the mathworks site about strjoin reads:
Starting in R2016b, the join function is recommended to join elements of a string array.
>> C = {'one','two','three'};
>> join(C) %same result as: >> join(C, ' ')
ans =
string
"one two three"
>> join(C, ', and-ah ')
ans =
string
"one, and-ah two, and-ah three"
Personally I like Alex' solution as well, as older versions of Matlab are abundant in research groups around the world.

Resources