i am trying to check if NSString is in specific format. dd:dd:dd. I was thinking of NSRegularExpression. Something like
/^(\d)\d:\d\d:\d\d)$/ ?
Have you tried something like:
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"^\d{2}:\d{2}:\d{2}$"
options:0
error:&error];
NSUInteger numberOfMatches = [regex numberOfMatchesInString:string
options:0
range:NSMakeRange(0, [string length])];
(I haven't tested it, because I cannot right now, but it should be working)
I suggest to use RegexKitLite
With this and assuming that in dd:dd:dd 'd' actually stands for a digit from 0-9 it should be fairly easy to implement what you need given the additional comment from Grijesh.
Here's an example copied from the RegexKitLite page:
// finds phone number in format nnn-nnn-nnnn
NSString *regEx = #"{3}-[0-9]{3}-[0-9]{4}";
NSString *match = [textView.text stringByMatching:regEx];
if ([match isEqual:#""] == NO) {
NSLog(#"Phone number is %#", match);
} else {
NSLog(#"Not found.");
}
UPDATE:
NSString *idRegex = #"[0-9][0-9]:[0-9][0-9]:[0-9][0-9]";
NSPredicate *idTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", idRegex];
for (NSString * str in newArrAfterPars) {
if ([idTest evaluateWithObject:str]) {
}
}
Related
When I tried matching the string with the regex '^(34|37)' it does not work even after giving the correct one. Can anyone please point out or guide me to what I am doing wrong?
This is my code:
NSPredicate *myTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", #"^(34|37)"];
if([myTest evaluateWithObject: #"378282246310005"]){
NSLog(#"match");
}
Your regex will not match the given string. That is ^(34|37) does not match 378282246310005. It matches the first two characters, but after that it fails because the string contains more characters, while your regex terminates.
You need to alter your regex to match the rest of the characters, even if you don't want to capture them. Try changing your regext to ^(34|37).*.
Make seprate method for matching regex as bool type. Then it will work.
like this
- (IBAction)tapValidatePhone:(id)sender
{
if(![self validateMobileNo:self.txtPhoneNo.text] )
{
NSLog(#"Mobile No. is not valid");
}
}
-(BOOL) validateMobileNo:(NSString *) paramMobleNo
{
NSString *phoneNoRegex = #"^(34|37)";
NSPredicate *phoneNoTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#",phoneNoRegex];
return [phoneNoTest evaluateWithObject:#"3435"];
}
it is not going in else condition.
Why not just use hasPrefix:
if([#"378282246310005" hasPrefix:#"34"] || [#"378282246310005" hasPrefix:#"37"])
{
NSLog(#"found it");
}
EDIT:
Using NSPredicate:
NSPredicate *myTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", #"^3(4|7)\\d+$"];
if([myTest evaluateWithObject: #"378282246310005"])
{
NSLog(#"match");
}
else
{
NSLog(#"notmatch");
}
Using NSRegularExpression:
NSError *error = nil;
NSString *testStr = #"348282246310005";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"^3(4|7)" options:NSRegularExpressionCaseInsensitive error:&error];
NSInteger matches = [regex numberOfMatchesInString:testStr options:NSMatchingReportCompletion range:NSMakeRange(0, [testStr length])];
if(matches > 0 )//[myTest evaluateWithObject: #"378282246310005"])
{
NSLog(#"match");
}
else
{
NSLog(#"notmatch");
}
BTW: (34|37) does not look 34 or 37 instead it seems 347 or 337 to me, since engine will pick 4|3 either 4 or 3.
Basically I'm looking for a good example of matching HTML (also newlines and whitespace) using NSRegularExpression.
I have this PHP code I wrote a while back:
preg_match_all("/<dt>(.+?)<\/dt>\W+<dd>(.+?)<\/dd>/si", $data, $m['deets']);
Now I know this works in PHP but for the life of me I can't translate it to Objective-C. Here was my attempt.
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"<dt>(.+?)<\/dt>\W+<dd>(.+?)<\/dd>" options:(NSRegularExpressionCaseInsensitive) error:&error];
return [regex matchesInString:target options:NSCaseInsensitiveSearch range:NSMakeRange(0, [target length])];
My target in this case is a bunch of HTML.
I never used NSRegularExpression, but NSPredicate instead :
NSError *error = NULL;
NSString* pattern = #"/<dt>(.+?)<\/dt>\W+<dd>(.+?)<\/dd>/si";
NSPredicate* predicate = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", pattern];
if ([predicate evaluateWithObject:myTargetString] == YES) {
// Okay
} else {
// Not found
}
Hope this helps.
EDIT :
NSPredicate is cool, be don't work if you want to get the matching range of your target string.
Your code is right, but the problem comes from the regexp expression, you must escape your \ characters and not escape / ones.
#"<dt>(.+?)</dt>\\W+<dd>(.+?)</dd>"
So :
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"<dt>(.+?)</dt>\\W+<dd>(.+?)</dd>" options:(NSRegularExpressionCaseInsensitive) error:&error];
return [regex matchesInString:target options:NSCaseInsensitiveSearch range:NSMakeRange(0, [target length])];
I would like to be able to take the numbers lying behind the ` symbol and in front of any character that is non-numerical and convert it into a integer.
Ex.
Original String: 2*3*(123`)
Result: 123
Original String: 4`12
Result: 4
Thanks,
Regards.
You can use regular expressions. You can find all the occurrences like this:
NSString *mystring = #"123(12`)456+1093`";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"([0-9]+)`" options:0 error:nil];
NSArray *matches = [regex matchesInString:mystring options:0 range:NSMakeRange(0, mystring.length)];
for (NSTextCheckingResult *match in matches) {
NSLog(#"%#", [mystring substringWithRange:[match rangeAtIndex:1]]);
}
// 12 and 1093
If you only need one occurrence, then replace the for loop with the following:
if (matches.count>0) {
NSTextCheckingResult *match = [matches objectAtIndex:0];
NSLog(#"%#", [mystring substringWithRange:[match rangeAtIndex:1]]);
}
There can be better way to do this, Quickly i could come up with this,
NSString *mystring = #"123(12`)";
NSString *neededString = nil;
NSScanner *scanner =[NSScanner scannerWithString:mystring];
[scanner scanUpToString:#"`" intoString:&neededString];
neededString = [self reverseString:neededString];
NSLog(#"%#",[self reverseString:[NSString stringWithFormat:#"%d",[neededString intValue]]]);
To reverse a string you can see this
Let's assume I have the string:
"I love visiting http://www.google.com"
How can I detect the token, http://www.google.com?
You can use NSDataDetectors These were added in iOS4 and are quite useful. You want to create a data detector with the NSTextCheckingTypeLink and let it do its thing.
NSString *testString = #"Hello http://google.com world";
NSDataDetector *detect = [[NSDataDetector alloc] initWithTypes:NSTextCheckingTypeLink error:nil];
NSArray *matches = [detect matchesInString:testString options:0 range:NSMakeRange(0, [testString length])];
NSLog(#"%#", matches);
You could do something like:
-(BOOL)textIsUrl:(NSString*)someString {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF MATCHES ^[-a-zA-Z0-9#:%_\\+.~#?&//=]{2,256}\\.[a-z]{2,4}\\b(\\/[-a-zA-Z0-9#:%_\\+.~#?&//=]*)?$"];
[predicate evaluateWithObject:someString];
}
I want to strip image URLs from lots of differently formed HTML.
I have this already:
NSRegularExpression *regex = [[NSRegularExpression alloc]
initWithPattern:#"(?<=img src=\").*?(?=\")"
options:NSRegularExpressionCaseInsensitive error:nil];
this works fine if the HTML is formed like <img src="someurl.jpg" alt="" .../> , but this isn't always the case, sometimes the there are other attributes before src which is doesn't pick up.
Its a difficult thing to do with regular expressions. You are generally better off with using an XMLParser and XPath. However, if the HTML isn't very valid (even if you use TidyHTML), you can find that XPath just won't work very well.
If you must look for images using regular expressions, I would suggest something like:
<\\s*?img\\s+[^>]*?\\s*src\\s*=\\s*([\"\'])((\\\\?+.)*?)\\1[^>]*?>
So assuming you have rawHTML in a string with the same name, use:
NSRegularExpression* regex = [[NSRegularExpression alloc] initWithPattern:#"<\\s*?img\\s+[^>]*?\\s*src\\s*=\\s*([\"\'])((\\\\?+.)*?)\\1[^>]*?>" options:NSRegularExpressionCaseInsensitive error:nil];
NSArray *imagesHTML = [regex matchesInString:rawHTML options:0 range:NSMakeRange(0, [rawHTML length])];
[regex release];
If you want to get out the actual image URL from the source then I'd use something like (run over the output from previous regex):
(?i)\\b((?:[a-z][\\w-]+:(?:/{1,3}|[a-z0-9%])|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,4}/)(?:[^\\s()<>]+|\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\))+(?:\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\)|[^\\s`!()\\[\\]{};:'\".,<>?«»“”‘’]
Yeah, I know, crazy! But you did ask :-)
Credit: That final regex is from John Gruber/Daring Fireball.
This is some code I've written in the past that returns an array of NSString url's of images. I use it when trying (as a last resort) to get image URL's from very broken HTML:
- (NSArray *)extractSuitableImagesFromRawHTMLEntry:(NSString *)rawHTML {
NSMutableArray *images = [[NSMutableArray alloc] init];
if(rawHTML!=nil&&[rawHTML length]!=0) {
NSRegularExpression* regex = [[NSRegularExpression alloc] initWithPattern:#"<\\s*?img\\s+[^>]*?\\s*src\\s*=\\s*([\"\'])((\\\\?+.)*?)\\1[^>]*?>" options:NSRegularExpressionCaseInsensitive error:nil];
NSArray *imagesHTML = [regex matchesInString:rawHTML options:0 range:NSMakeRange(0, [rawHTML length])];
[regex release];
for (NSTextCheckingResult *image in imagesHTML) {
NSString *imageHTML = [rawHTML substringWithRange:image.range];
NSRegularExpression* regex2 = [[NSRegularExpression alloc] initWithPattern:#"(?i)\\b((?:[a-z][\\w-]+:(?:/{1,3}|[a-z0-9%])|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,4}/)(?:[^\\s()<>]+|\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\))+(?:\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\)|[^\\s`!()\\[\\]{};:'\".,<>?«»“”‘’]))" options:NSRegularExpressionCaseInsensitive error:nil];
NSArray *imageSource=[regex2 matchesInString:imageHTML options:0 range:NSMakeRange(0, [imageHTML length])];
[regex2 release];
NSString *imageSourceURLString=nil;
for (NSTextCheckingResult *result in imageSource) {
NSString *str=[imageHTML substringWithRange:result.range];
//DebugLog(#"url is %#",str);
if([str hasPrefix:#"http"]) {
//strip off any crap after file extension
//find jpg
NSRange r1=[str rangeOfString:#".jpg" options:NSBackwardsSearch&&NSCaseInsensitiveSearch];
if(r1.location==NSNotFound) {
//find jpeg
NSRange r2=[str rangeOfString:#".jpeg" options:NSBackwardsSearch&&NSCaseInsensitiveSearch];
if(r2.location==NSNotFound) {
//find png
NSRange r3=[str rangeOfString:#".png" options:NSBackwardsSearch&&NSCaseInsensitiveSearch];
if(r3.location==NSNotFound) {
break;
} else {
imageSourceURLString=[str substringWithRange:NSMakeRange(0, r3.location+r3.length)];
}
} else {
//jpeg was found
imageSourceURLString=[str substringWithRange:NSMakeRange(0, r2.location+r2.length)];
break;
}
} else {
//jpg was found
imageSourceURLString=[str substringWithRange:NSMakeRange(0, r1.location+r1.length)];
break;
}
}
}
if(imageSourceURLString==nil) {
//DebugLog(#"No image found.");
} else {
DebugLog(#"*** image found: %#", imageSourceURLString);
NSURL *imageURL=[NSURL URLWithString:imageSourceURLString];
if(imageURL!=nil) {
[images addObject:imageURL];
}
}
}
}
return [images autorelease];
}