How do I output a literal sequence with NSLog - iphone

I want NSLogto output a literal escape sequence, without treating it as a pattern.
Take, for example NSLog(#"image%03d.jpg");, who's output I want to be the actual contents, image%03d.jpg instead of image000.jpg.
I've tried various escape sequences like NSLog(#"image\\%03d.jpg");, NSLog(#"image\\%03\\d.jpg"); and NSLog(#"image%03\\d.jpg");, none of which yielded the expected results.
The problem only grows further when I'm including an actual pattern that I do want to replace, after the literal one: NSLog(#"image\\%03d.jpg test %d", 1);, that I'd like to output image%03d.jpg test 1.

Use two %% characters and you will get the desired results:
NSLog(#"image%%03d.jpg");

Related

match string pattern by certain characters but exclude combinations of those characters

I have the following sample string:
'-Dparam="x" -f hello-world.txt bye1.txt foo_bar.txt -Dparam2="y"'
I am trying to use RegEx (PowerShell, .NET flavor) to extract the filenames hello-world.txt, bye1.txt, and foo_bar.txt.
The real use case could have any number of -D parameters, and the -f <filenames> argument could appear in any position between these other parameters. I can't easily use something like split to extract it as the delimiter positioning could change, so I thought RegEx might be a good proposition here.
My attempt is something like this in PowerShell (can be opened on any Windows system and copy pasted into it):
'-Dparam="x" -f hello-world.txt bye1.txt foo_bar.txt -Dparam2="y"' -replace '^.* -f ([a-zA-Z0-9_.\s-]+).*$','$1'
Desired output:
hello-world.txt bye1.txt foo_bar.txt
My problem is that I either only take hello-world.txt, or I get hello-world.txt all the way to the end of the string or next = symbol (as in the example above).
I am having trouble expressing that \s is allowed, since I need to capture multiple space-delimited filenames, but that the combination of \s-[a-zA-Z] is not allowed, as that indicates the start of the next argument.

getting the path name files in a directory in q

I am using q to get all the files listed in that directory:
key `:Dname
and then try to filter out the the ones that start with numbers as:
key `:Dname like "[0-9]"
but the like part does not quite work. I tried get as well since I like the path to include the directory that the file is in.
Keep in mind that q evaluate expressions from right to left. Your code here will first evaluate
`:Dname like "[0-9]"
and apply key to the result.
You want something closer to
key[`:Dname] like "[0-9]"
But to get what you want you'll have to add a wildcard to the pattern string that you're supplying and apply not to the result
not key[`:Dname] like "[0-9]*"
This will give you a boolean vector, to return the list of files you want use where and index:
key[`:Dname] where not key[`:Dname] like "[0-9]*"
If you have a filename defined like
filename:`2019.01.20file.txt
You can compare this to a pattern using like, similar to what you have done:
filename like "[0-9]*"
"*" is the wildcard symbol which means that anything can come after the [0-9]
like compares a string or symbol to a pattern
So this line return a 1b if the filename starts with a digit between 0 and 9.
Another method would be to compare the start of the filename to .Q.n which is a string of 0-9.
This can be achieved like so:
first[string filename] in .Q.n
string converts the symbol to a string for in to compare it to the string .Q.n
For your situation, I would recommend the first method.
q)key `:q
`README.txt`q.k`q.q`s.k`sp.q`w32
q)key[`:q] like "q*"
011000b
q)x where (x:key[`:q]) like "q*"
`q.k`q.q
q)x where not (x:key[`:q]) like "q*"
`README.txt`s.k`sp.q`w32
This method returns the Boolean list which indicates whether each file starts with "q":
Uses not to reverse the 1s and 0s of this list
Uses where to return the indexes at which the Boolean list is equal to 1
Indexes into key[`:q] with this list
I hope this helps

finding a comma in string

[23567,0,0,0,0,0] and other value is [452221,0,0,0,0,0] and the value should be contineously displaying about 100 values and then i want to display only the sensor value like in first sample 23567 and in second sample 452221 , only the these values have to display . For that I have written a code
value = str2double(str(2:7));see here my attempt
so I want to find the comma in the output and only display the value before first comma
As proposed in a comment by excaza, MATLAB has dedicated functions, such as sscanf for such purposes.
sscanf(str,'[%d')
which matches but ignores the first [, and returns the next (i.e. the first) number as a double variable, and not as a string.
Still, I like the idea of using regular expressions to match the numbers. Instead of matching all zeros and commas, and replacing them by '' as proposed by Sardar_Usama, I would suggest directly matching the numbers using regexp.
You can return all numbers in str (still as string!) with
nums = regexp(str,'\d*','match')
and convert the first number to a double variable with
str2double(nums{1})
To match only the first number in str, we can use the regexp
nums = regexp(str,'[(\d*),','tokens')
which finds a [, then takes an arbitrary number of decimals (0-9), and stops when it finds a ,. By enclosing the \d* in brackets, only the parts in brackets are returned, i.e. only the numbers without [ and ,.
Final Note: if you continue working with strings, you could/should consider the regexp solution. If you convert it to a double anyways, using sscanf is probably faster and easier.
You can use regexprep as follows:
str='[23567,0,0,0,0,0]' ;
required=regexprep(str(2:end-1),',0','')
%Taking str(2:end-1) to exclude brackets, and then removing all ,0
If there can be values other than 0 after , , you can use the following more general approach instead:
required=regexprep(str(2:end-1),',[-+]?\d*\.?\d*','')

Sorting Data in Matlab

I am trying to sort the following data in the Matlab, but not getting the expected output what I need.
Here is data:
'1B-3A-5A'
'1A-3A-19A'
'2A-2A-4A-5A'
'2B-2A-5A'
'2A-4A-5A'
'2C-5A-30A'
'11A-3A-19A
'3A-19A-42C'
'4A-4A-12A'
'19A-21A-42C'
'25A-41D'
'41C-41C'
'39C-41C'
'43E'
'39A-41D'
'1A-3A-5A-7A'
'7C-27A-28A'
I need the sorted list such that it considers the first number then the alphabet to sort the list like below
'1A-3A-19A'
'1A-3A-5A-7A'
'1B-3A-5A'
'2A-2A-4A-5A'
'2A-4A-5A'
'2B-2A-5A'
'2C-5A-30A'
'3A-19A-42C'
'4A-4A-12A'
'7C-27A-28A'
'11A-3A-19A
'19A-21A-42C'
'25A-41D'
'39A-41D'
'39C-41C'
'41C-41C'
'43E'
Can you please suggest a way to do it? I tried all ways but it doesn't sort it like I want. Thanks!!
How about using sort or sortrows? This does actually sort strings as well:
If A is a string, then sort(A) sorts according to the ASCII dictionary order. The sort is case sensitive with uppercase letters appearing in the output before the lowercase letters.
As #StewieGriffin pointed out, this sorts 11a before 1a. Conveniently Douglas Schwarz has already produced a code that overcomes exactly this problem of alphanumeric sorting on numerics first and characters after.

Checking the format of a string in Matlab

So I'm reading multiple text files in Matlab that have, in their first columns, a column of "times". These times are either in the format 'MM:SS.milliseconds' (sorry if that's not the proper way to express it) where for example the string '29:59.9' would be (29*60)+(59)+(.9) = 1799.9 seconds, or in the format of straight seconds.milliseconds, where '29.9' would mean 29.9 seconds. The format is the same for a single file, but varies across different files. Since I would like the times to be in the second format, I would like to check if the format of the strings match the first format. If it doesn't match, then convert it, otherwise, continue. The code below is my code to convert, so my question is how do I approach checking the format of the string? In otherwords, I need some condition for an if statement to check if the format is wrong.
%% Modify the textdata to convert time to seconds
timearray = textdata(2:end, 1);
if (timearray(1, 1) %{has format 'MM.SS.millisecond}%)
datev = datevec(timearray);
newtime = (datev(:, 5)*60) + (datev(:, 6));
elseif(timearray(1, 1) %{has format 'SS.millisecond}%)
newtime = timearray;
You can use regular expressions to help you out. Regular expressions are methods of specifying how to search for particular patterns in strings. As such, you want to find if a string follows the formats of either:
xx:xx.x
or:
xx.x
The regular expression syntax for each of these is defined as the following:
^[0-9]+:[0-9]+\.[0-9]+
^[0-9]+\.[0-9]+
Let's step through how each of these work.
For the first one, the ^[0-9]+ means that the string should start with any number (^[0-9]) and the + means that there should be at least one number. As such, 1, 2, ... 10, ... 20, ... etc. is valid syntax for this beginning. After the number should be separated by a :, followed by another sequence of numbers of at least one or more. After, there is a . that separates them, then this is followed by another sequence of numbers. Notice how I used \. to specify the . character. Using . by itself means that the character is a wildcard. This is obviously not what you want, so if you want to specify the actual . character, you need to prepend a \ to the ..
For the second one, it's almost the same as the first one. However, there is no : delimiter, and we only have the . to work with.
To invoke regular expressions, use the regexp command in MATLAB. It is done using:
ind = regexp(str, expression);
str represents the string you want to check, and expression is a regular expression that we talked about above. You need to make sure you encapsulate your expression using single quotes. The regular expression is taken in as a string. ind would this return the starting index of your string of where the match was found. As such, when we search for a particular format, ind should either be 1 indicating that we found this search at the beginning of the string, or it returns empty ([]) if it didn't find a match. Here's a reproducible example for you:
B = {'29:59.9', '29.9', '45:56.8', '24.5'};
for k = 1 : numel(B)
if (regexp(B{k}, '^[0-9]+:[0-9]+\.[0-9]+') == 1)
disp('I''m the first case!');
elseif (regexp(B{k}, '^[0-9]+\.[0-9]+') == 1)
disp('I''m the second case!');
end
end
As such, the code should print out I'm the first case! if it follows the format of the first case, and it should print I'm the second case! if it follows the format of the second case. As such, by running this code, we get:
I'm the first case!
I'm the second case!
I'm the first case!
I'm the second case!
Without knowing how your strings are formatted, I can't do the rest of it for you, but this should be a good start for you.