How can I find a dynamic number in a long NSString? - iphone

I have a very big NSString, which holds around 1500 characters in it. In this string I need to extract a phone number, which may change frequently, as it is a dynamic data. The phone number will be in the format of 251-221-2000, how can I extract this?

Check out this previous question on regular expressions and NSString.
Search through NSString using Regular Expression
In your case an appropriate regular expression would be #"\\d{3}-\\d{3}-\\d{4}".

This sounds like a perfect candidate for a regular expression. You can use the NSRegularExpression class to achieve this. You can test your regular expression at http://www.regextester.com

NSString *yourString = #"Your 1500 characters string ";
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:#"\d{3}-\d{3}-\d{4}"
options:NSRegularExpressionCaseInsensitive
error:&error];
[regex enumerateMatchesInString:yourString options:0 range:NSMakeRange(0, [yourString length]) usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop){
// your code to handle matches here
}];
Let me know it is working or not.

Related

NSRegularExpression not getting exact text

I have a string like:
<book>MyBook</book><value>myValue</value>
Now I want to get the text "myValue" out of this string. I want to use NSRegularExpression to do this. I tried this:
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"(<book>MyBook</book>\\s*<value>).*?(</value>)"
options:NSRegularExpressionCaseInsensitive
error:&error];
NSArray *textArray = [regex matchesInString:myData options:0 range:NSMakeRange(0, [myData length])];
NSTextCheckingResult * result = [rege firstMatchInString:myData
options:0
range:NSMakeRange(0, [myData length])];
The result is:
<book>MyBook</book><value>myValue</value>
So I get the whole string, but I only want "myValue". How can I do this? What am I missing here?
Thanks in advance!
That happens because you wrote a regex that matches the entire string. I'd reckon that writing a regex that will only match the myValue part of the string is way too complicated to be bothered with (due to the fact that you've got MyBook string that will probably match anything myValue does).
I'd recommend not using regex for this, as they are not intended for the use you've described here. If you don't want to use any XML deserialization, you could use a NSScanner or any of the NSString class methods which will yield a simpler, and easier code to maintain.
For example, using an NSScanner and a few other methods:
NSString *stringToBeScanned = #"<book>MyBook</book><value>myValue</value>";
NSString *myValue;
NSScanner *scanner = [NSScanner scannerWithString:stringToBeScanned];
[scanner scanUpToString:#"<value>" intoString:nil];
// After the above, we've got "<value>myValue</value>" left to scan
[scanner scanUpToString:#"</value>" intoString:&myValue];
// We ended up with a "<value>myValue" type of a string
// This will trim the remaining of the string we don't need
myValue = [myValue stringByReplacingOccurrencesOfString:#"<value>" withString:#""];
The above could probably be written better and I might have made a mistake or two writing it out my head, but the principle should work.

Regular Expression in Objective-C

I want to replace all tags which are like <xxxx>.
I tried this:
- (NSString *)grabData:(NSString *)searchTerm {
// Setup an error to catch stuff in
NSError *error = NULL;
//Create the regular expression to match against
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"<.*>" options:NSRegularExpressionCaseInsensitive error:&error];
// create the new string by replacing the matching of the regex pattern with the template pattern(whitespace)
NSString *newSearchString = [regex stringByReplacingMatchesInString:searchTerm options:0 range:NSMakeRange(0, [searchTerm length]) withTemplate:#""];
NSLog(#"New string: %#",newSearchString);
return newSearchString;
}
But this just doesn't work. Could anyone help me?
The pattern <.*> matches a less-than, any amount of anything including a greater than, and then a greater-than. This pattern would, for instance, match a complete HTML file...
What you need is a <[^>]+> the [^>] is the set of all characters excluding greater-than, the + is "one or more", so the whole thing matches a less-than, one or more of anything excluding a greater than, and then a greater-than.
Your regular expression is incorrect.
< and > are meta characters and need escaping
The pattern matching should be .+
Based on this use
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"\\<.+\\>" options:NSRegularExpressionCaseInsensitive error:&error];
and it should work

How to find twitter handles in a NSString

If I had the following:
NSString *tweet = #"Shoutout to #somebody and #somebodyElse for your help on this one #shoutouts";
How would i go about finding the range of the twitter handles (eg #somebody)??
I want to make them bold in my Attributed String which is the next step.
Bonus points if you can help me find the # hash tags as well, but I assume its the same algorithm.
NSRegularExpression is your friend.
Use NSRegularExpression class,
http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSRegularExpression_Class/Reference/Reference.html
Than trying using this online tool to build Regex,
http://www.gskinner.com/RegExr/
I tried this and it seems like you can build a good one,
SAMPLE CODE - NOT TESTED
NSString *yourString = #"Shoutout to #somebody and #somebodyElse for your help on this one #shoutouts";
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:#"\#\S+|#\S+"
options:NSRegularExpressionCaseInsensitive
error:&error];
[regex enumerateMatchesInString:yourString options:0 range:NSMakeRange(0, [yourString length]) usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop){
// your code to handle matches here
}];
About test in online tool!
Good luck!

How to check if a string contains English letters (A-Z)?

How can I check whether a string contains the English Letters (A through Z) in Objective-C?
In PHP, there is preg_match method for that.
One approach would be to use regular expressions — the NSRegularExpression class. The following demonstrates how you could detect any English letters, but the pattern could be modified to match only if the entire string consists of such letters. Something like ^[a-zA-Z]*$.
NSRegularExpression *regex = [[[NSRegularExpression alloc]
initWithPattern:#"[a-zA-Z]" options:0 error:NULL] autorelease];
// Assuming you have some NSString `myString`.
NSUInteger matches = [regex numberOfMatchesInString:myString options:0
range:NSMakeRange(0, [myString length])];
if (matches > 0) {
// `myString` contains at least one English letter.
}
Alternatively, you could construct an NSCharacterSet containing the characters you're interested in and use NSString's rangeOfCharacterFromSet: to find the first occurrence of any one. I should note that this method only finds the first such character in the string. Maybe not what you're after.
Finally, I feel like you could do something with encodings, but haven't given this much thought. Perhaps determine if the string could be represented using ASCII (using canBeConvertedToEncoding:) and then check for numbers/symbols?
Oh, and you could always iterate over the string and check each character! :)
You can use simple NSPredicate test.
NSString *str = #"APPLE";
NSString *regex = #"[A-Z]+";
NSPredicate *test = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", regex];
BOOL result = [test evaluateWithObject:str];
You could also use NSCharacterSet and use the rangeOfCharacterFromSet: method to see if the returned NSRange is the entire range of the string. characterSetWithRange would be a good place to start to create your characterSet.
You can use the NSRegularExpression Class (Apple's documentation on the class can be viewed here)

what's the best way to detect if a word in NSString has a number?

example: word with number in string
NSString *str = [NSString stringWithFormat:#"this is an 101 example1 string"]
Since example1 has a number in the end and i want to remove it. I can break it into an array and filter it out using predicate, but that seems slow to me since I need to do like a million of these.
What would be a more efficient way?
Thanks!
Probably NSRegularExpression. I think ([^0-9 ]+)\d+|\d+([^0-9 ]+) should do it. Just replace it with $1.
Based on Chuck's response, here is the complete code in case someone might find it useful:
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"([^0-9 ]+)\\d+|\\d+([^0-9 ]+)"
options:NSRegularExpressionCaseInsensitive
error:&error];
NSString *modifiedString = [regex stringByReplacingMatchesInString:str2
options:0
range:NSMakeRange(0, [str2 length])
withTemplate:#"$1"];