obtain number from string in matlab - matlab

I have an array of strings:
dd = {'L','temp1','temp23','Reas'};
I would like to extract the numbers from the strings that contain any numbers (if that makes sense). So, the solution for this question should be 1 and 23.
How can I achieve this in matlab?

Here's part of the solution. Suppose
myString = 'temp23'
then the expression
str2double(a(isstrprop(a,'digit')))
will return
23
I haven't got the time to turn this into a function to deal with your array of strings but this should get you started.
#DennisJahruddin suggested the following completion of my answer. I haven't tested it thoroughly:
dd = {'L','temp1','temp23','Reas'};
ee = cellfun(#(a) str2double(a(isstrprop(a,'digit'))),dd);
ff = ee(~isnan(ee))

Related

Matlab,problem with concatenation in an iteration? How do I fix it?

The problem I have is that it only works partially, but what can I add to make it work?
A2 = [20 4 6 8 5];
A3 = [10 2 3 4 6];
Str=[];
formatSpec = 'P%d (%d,%d)';
for i=1:length(A2)
str = char(sprintf (formatSpec, i, A2(i),A3(i)));
Str=[Str;str];
end
set(handles.text2,'string',Str);
You are not concatenating strings but char-arrays. Thinking it this way, it already answers your question: If you have a two-digit number, the char-array is one element longer than the char-array of a single-digit number... and you cannot concatenate two arrays of different size vertically.
The solution is fairly simple: use actual strings (introduced somewhere around R2016a). Strings are indicated with "" instead of '', which are chars. So replace your charwith string and it works fine. (Even better: provide the formatSpecas ""-string and it sprintf() will return a string right away)
Side note:
BTW, you should always allocate memory if your are looping. That is why the Str has an orange squiggly underline. This is because MATLAB stores arrays in RAM contiguously and has to copy it to a larger section it it outgrows the current one.
So instead of Str=[], write Str = strings(length(A2),1), and index Str(i) = ... in the loop.
Personally, I like num2str more that sprintf but I cannot give a good reason for this, except for that it also works without providing a format.

Matlab: Function that returns a string with the first n characters of the alphabet

I'd like to have a function generate(n) that generates the first n lowercase characters of the alphabet appended in a string (therefore: 1<=n<=26)
For example:
generate(3) --> 'abc'
generate(5) --> 'abcde'
generate(9) --> 'abcdefghi'
I'm new to Matlab and I'd be happy if someone could show me an approach of how to write the function. For sure this will involve doing arithmetic with the ASCII-codes of the characters - but I've no idea how to do this and which types that Matlab provides to do this.
I would rely on ASCII codes for this. You can convert an integer to a character using char.
So for example if we want an "e", we could look up the ASCII code for "e" (101) and write:
char(101)
'e'
This also works for arrays:
char([101, 102])
'ef'
The nice thing in your case is that in ASCII, the lowercase letters are all the numbers between 97 ("a") and 122 ("z"). Thus the following code works by taking ASCII "a" (97) and creating an array of length n starting at 97. These numbers are then converted using char to strings. As an added bonus, the version below ensures that the array can only go to 122 (ASCII for "z").
function output = generate(n)
output = char(97:min(96 + n, 122));
end
Note: For the upper limit we use 96 + n because if n were 1, then we want 97:97 rather than 97:98 as the second would return "ab". This could be written as 97:(97 + n - 1) but the way I've written it, I've simply pulled the "-1" into the constant.
You could also make this a simple anonymous function.
generate = #(n)char(97:min(96 + n, 122));
generate(3)
'abc'
To write the most portable and robust code, I would probably not want those hard-coded ASCII codes, so I would use something like the following:
output = 'a':char(min('a' + n - 1, 'z'));
...or, you can just generate the entire alphabet and take the part you want:
function str = generate(n)
alphabet = 'a':'z';
str = alphabet(1:n);
end
Note that this will fail with an index out of bounds error for n > 26, so you might want to check for that.
You can use the char built-in function which converts an interger value (or array) into a character array.
EDIT
Bug fixed (ref. Suever's comment)
function [str]=generate(n)
a=97;
% str=char(a:a+n)
str=char(a:a+n-1)
Hope this helps.
Qapla'

Using fscanf in MATLAB to read an unknown number of columns

I want to use fscanf for reading a text file containing 4 rows with an unknown number of columns. The newline is represented by two consecutive spaces.
It was suggested that I pass : as the sizeA parameter but it doesn't work.
How can I read in my data?
update: The file format is
String1 String2 String3
10 20 30
a b c
1 2 3
I have to fill 4 arrays, one for each row.
See if this will work for your application.
fid1=fopen('test.txt');
i=1;
check=0;
while check~=1
str=fscanf(fid1,'%s',1);
if strcmp(str,'')~=1;
string(i)={str};
end
i=i+1;
check=strcmp(str,'');
end
fclose(fid1);
X=reshape(string,[],4);
ar1=X(:,1)
ar2=X(:,2)
ar3=X(:,3)
ar4=X(:,4)
Once you have 'ar1','ar2','ar3','ar4' you can parse them however you want.
I have found a solution, i don't know if it is the only one but it works fine:
A=fscanf(fid,'%[^\n] *\n')
B=sscanf(A,'%c ')
Z=fscanf(fid,'%[^\n] *\n')
C=sscanf(Z,'%d')
....
You could use
rawText = getl(fid);
lines = regexp(thisLine,' ','split);
tokens = {};
for ix = 1:numel(lines)
tokens{end+1} = regexp(lines{ix},' ','split'};
end
This will give you a cell array of strings having the row and column shape or your original data.
To read an arbitrary line of text then break it up according the the formating information you have available. My example uses a single space character.
This uses regular expressions to define the separator. Regular expressions powerful but too complex to describe here. See the MATLAB help for regexp and regular expressions.

Function to split string in matlab and return second number

I have a string and I need two characters to be returned.
I tried with strsplit but the delimiter must be a string and I don't have any delimiters in my string. Instead, I always want to get the second number in my string. The number is always 2 digits.
Example: 001a02.jpg I use the fileparts function to delete the extension of the image (jpg), so I get this string: 001a02
The expected return value is 02
Another example: 001A43a . Return values: 43
Another one: 002A12. Return values: 12
All the filenames are in a matrix 1002x1. Maybe I can use textscan but in the second example, it gives "43a" as a result.
(Just so this question doesn't remain unanswered, here's a possible approach: )
One way to go about this uses splitting with regular expressions (MATLAB's strsplit which you mentioned):
str = '001a02.jpg';
C = strsplit(str,'[a-zA-Z.]','DelimiterType','RegularExpression');
Results in:
C =
'001' '02' ''
In older versions of MATLAB, before strsplit was introduced, similar functionality was achieved using regexp(...,'split').
If you want to learn more about regular expressions (abbreviated as "regex" or "regexp"), there are many online resources (JGI..)
In your case, if you only need to take the 5th and 6th characters from the string you could use:
D = str(5:6);
... and if you want to convert those into numbers you could use:
E = str2double(str(5:6));
If your number is always at a certain position in the string, you can simply index this position.
In the examples you gave, the number is always the 5th and 6th characters in the string.
filename = '002A12';
num = str2num(filename(5:6));
Otherwise, if the formating is more complex, you may want to use a regular expression. There is a similar question matlab - extracting numbers from (odd) string. Modifying the code found there you can do the following
all_num = regexp(filename, '\d+', 'match'); %Find all numbers in the filename
num = str2num(all_num{2}) %Convert second number from str

How can I round to a certain floating-point precision?

I think it's a simple question. I want:
a = 1.154648126486416;
to become:
a = 1.154;
and not:
a = 1.15000000000;
How do I do that without using format('bank').
You could do this:
a = floor(a*1000)/1000;
Building on #gnovice's answer, you can format the output as a string to get rid of the extra zeros. See the sprintf documentation for all the formatting options.
str=sprintf('The result is %1.3f.',a);
disp(str)
will show "The result is 1.154." in the command prompt. Or write the string to file, etc., etc.
a = 1.154648126486416;
% desired precision
b = -3;
% your answer
ans = floor(a*10^(-b))/(10^(-b));
The answer is 1.1540
this is good if you don't care about the rest of digits but if you do care then you just have to simply change "floor" to "round".
ans = round(a*10^(-b))/(10^(-b));
The answer is 1.1550