NSPredicate, with quotes / without quotes - iphone

In my iPhone app, I'm reading a csv file. The relevant line is this:
NSString *countrycode = [[[NSString alloc] initWithFormat:#"%#", [arr objectAtIndex:2]]
stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
This returns "CN" (which stands for China).
When I do this:
NSLog(#"Manual: %#, country code: %#",#"CN",countryCode);
I get:
Manual: CN, country code: "CN"
One has quotes and the other does not. I don't know why this is.
The reason this is tripping me up is the following:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"countrycode == %# ", #"CN"];
This works fine, and returns China from Core Data.
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"countrycode == %# ", countrycode];
This fails to return anything. I am assuming this is because it has quotes around it, or something, although perhaps I am incorrect.
What am I doing wrong here?

Actually the correct way to format a predicate to exclude quotes is the to use %K versus %#. See Predicate Format String Syntax.

Your countryCode variable must have quotes inside of it when it's read back. The first time you assign the literal #"CN" the quotes are removed as they specify that your variable is an NSString. They aren't really inside of the literal string. If you wanted strings inside of the first CN, you'd need to explicitly specify the quotation marks, e.g. #"""CN"""
However, if you want to get rid of any quotations in the second string, you could always do this to the string prior to putting it into your predicate:
[countryCode stringByReplacingOccurrencesOfString:#"""" withString:#""];

Related

swift Using predicate

request.predicate=NSPredicate( format:"lnameID= \(light.valueForKey("lnameID"))",nil);
When using the request.predicate in Swift,it goes wrong.
How to solve the problem in the format " xx "xx" xx" ?
You should not use string interpolation when building predicates. This will give wrong
results or crash at runtime as soon as there are any special characters (like
single or double quotes) in the values.
Better use the %# placeholder, for example:
let lnameID = light.valueForKey("lnameID") as String // assuming that it is a string
request.predicate = NSPredicate(format: "lnameID = %#", lnameID)
You can put escaped quotes around and the escaped variable within the string like so:
request.predicate=NSPredicate( format:"lnameID= \"\(light.valueForKey("lnameID"))\"",nil)
Or you can use a placeholder, %#, where quotes are generated, as seen in Martin R's answer. Using escaped quotes is the more native way to do it in swift.

Find occurrence of substring in sentence only if word starts with substring

If I have 2 strings:
"My name is Eric"
"America is great"
And my substring is 'eri'.
How can I write a function that will only return true for the first sentence, because it has a WORD that starts with eri (Eric) and does not just contain eri (AmERIca).
Note;
I have been using NSPredicates, but using CONTAINS would return both, and using BEGINSWITH would only check the first word.
This string is also contained in an Object, say and the property is called ,
so my current code is:
NSPredicate *resultPredicate = [NSPredicate
predicateWithFormat:#"SELF.name contains[cd] %#",
searchText];
searchResults = [[myArray filteredArrayUsingPredicate:resultPredicate] mutableCopy];
Why not search for a string with leading space, like " eri"? That will automatically only find actual words and not something in the middle.

How to use regular expression in iPhone app to separate string by , (comma)

I have to read .csv file which has three columns. While parsing the .csv file, I get the string in this format Christopher Bass,\"Cry the Beloved Country Final Essay\",cbass#cgs.k12.va.us. I want to store the values of three columns in an Array, so I used componentSeparatedByString:#"," method! It is successfully returning me the array with three components:
Christopher Bass
Cry the Beloved Country Final Essay
cbass#cgs.k12.va.us
but when there is already a comma in the column value, like this
Christopher Bass,\"Cry, the Beloved Country Final Essay\",cbass#cgs.k12.va.us
it separates the string in four components because there is a ,(comma) after the Cry:
Christopher Bass
Cry
the Beloved Country Final Essay
cbass#cgs.k12.va.us
so, How can I handle this by using regular expression. I have "RegexKitLite" classes but which regular expression should I use. Please help!
Thanks-
Any regular expression would probably turn out with the same problem, what you need is to sanitize your entries or strings, either by escaping your commas or by highlighting strings this way: "My string". Otherwise you will have the same problem. Good luck.
For your example you would probably need to do something like:
\"Christopher Bass\",\"Cry\, the Beloved Country Final Essay\",\"cbass#cgs.k12.va.us\"
That way you could use a regexp or even the same method from the NSString class.
Not related at all, but the importance of sanitizing strings: http://xkcd.com/327/ hehehe.
How about this:
componentsSeparatedByRegex:#",\\\"|\\\","
This should split your string whereever " and , appear together in either order, resulting in a three-member array. This of course assumes that the second element in the string is always enclosed in parentheses, and the characters " and , never appear consecutively within the three components.
If either of these assumptions is incorrect, other methods to identify string components may be used, but it should be made clear that no generic solution exists. If the three component strings can contain " and , anywhere, not even a limited solution is possible in such cases:
Doe, John,\"\"Why Unescaped Strings Suck\", And Other Development Horror Stories\",Doe, John <john.doe#dev.null>
Hopefully there is nothing like the above in your CSV data. If there is, the data is basically unusable, and you should look into a better CSV exporter.
The regex you're searching for is: \\"(.*)\\"[ ^,]*|([^,]*),
in ObjC: (('\"' && string_1 && '\"' && 0-n spaces) || string_2 except comma) && comma
NSString *str = #"Christopher Bass,\"Cry, the Beloved Country ,Final Essay\",cbass#cgs.k12.va.us,som";
NSString *regEx = #"\\\"(.*)\\\"[ ^,]*|([^,]*),";
NSMutableArray *split = [[str componentsSeparatedByRegex:regEx] mutableCopy];
[split removeObject:#""]; // because it will print always both groups even if the other is empty
NSLog(#"%#", split);
// OUTPUT:
2012-02-07 17:42:18.778 tmpapp[92170:c03] (
"Christopher Bass",
"Cry, the Beloved Country ,Final Essay",
"cbass#cgs.k12.va.us",
som
)
RegexKitLite will add both strings to the array, therefore you will end up with empty objects for your array. removeObject:#"" will delete those but if you need to maintain true empty values (eg. your source has val,,ue) you have to modify the code to the following:
str = [str stringByReplacingOccurrencesOfRegex:regEx withString:#"$1$2∏"];
NSArray *split = [str componentsSeparatedByString:#"∏"];
$1 and $2 are those two strings mentioned above, ∏ is in this case a character which will most likely never appear in normal text (and is easy to remember: option-shift-p).
The last part looks like it will never contain a comma. Neither will the first one as far as I can see...
What about splitting the string like this:
NSArray *splitArr = [str componentsSeparatedByString:#","];
NSString *nameStr = [splitArr objectAtIndex:0];
NSString *emailStr = [splitArr lastObject];
NSString *contentStr = #"";
for(int i=1; i<[splitArr count]-1; ++i) {
contentStr = [contentStr stringByAppendingString:[splitArr objectAtIndex:i]];
}
This will use the first and last string as is, and combine the rest into the content.
Kind of a hack, but a name and an email address will never contain a comma, right?
Is the title guarantied to have the quotation marks? And is it the only component that can have them? Because then componentSeparatedByString:#"\"" should get you this:
Christopher Bass,
Cry, the Beloved Country Final Essay
,cbass#cgs.k12.va.us
Then use componentSeparatedByString:#"," or substringFrom/ToIndex: to get rid of the two commas in the first and last component.
Here's a solution using substring:
NSString* input = #"Christopher Bass,\"Cry, the Beloved Country Final Essay\",cbass#cgs.k12.va.us";
NSArray* split = [input componentsSeparatedByString:#"\""];
NSString* part1 = [split objectAtIndex:0];
NSString* part2 = [split objectAtIndex:1];
NSString* part3 = [split objectAtIndex:2];
part1 = [part1 substringToIndex:[part1 length] - 1];
part3 = [part3 substringFromIndex:1];
NSLog(part1);
NSLog(part2);
NSLog(part3);

Why does nspredicate crash?

I wanted to check if a field contains data or not. Here's my code:
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:
#"( SeriesStudyID == %# )" ,"" ]];
But it crashes. Why?
#iAnand's answer is wrong. Using %# in a predicate format string is perfectly acceptable.
The problem is that %# means to substitute in an object, but you're substituting in "", which is not an object, but a char*. Thus, you need to simply add an # sign in front of the double quotes to turn it from a char* into an NSString.

Regular expression for numbers

I need a regular expression to detect at least one number in a string. Other characters can be anything. Please help me to implement this in objective C.
Regards,
Dilshan
\d+
Match one or more digit.
This is a very similar question to:
Regular Expressions in Objective-C and Core Data
Check ICU Regex Documentation for figuring out your regular expression needs
To match a digit anywhere in string use .*\\d.*. To implement in objective-c use NSPredicate try something like this:
NSString *matchphrase = #".*\\d.*";
BOOL match = NO;
NSString *item = #"string with d1g1it";
NSPredicate *matchPred = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", matchphrase];
match = [matchPred evaluateWithObject:item];
More here
Edited according Dislhan comment.