Regex help in objective c - objective-c

<NSSimpleRegularExpressionCheckingResult: 0x100217890>{0, 4}{<NSRegularExpression: 0x100214700> test 0x1}
This is one element in the array which stores the result of a regular expression search.
I've got what I want: 'test'. I don't however want all the stuff around it ie
<NSSimpleRegularExpressionCheckingResult: 0x100217890>{0, 4}{<NSRegularExpression: 0x100214700> etc
I've got a feeling I'm going to have to send something to this element ie
[element stringValue];
but I need a little help discovering what that is..
My full code is below:
NSString *test = #"test 123 test";
NSRegularExpression* regex = [[NSRegularExpression alloc] initWithPattern:#"test" options:NSRegularExpressionCaseInsensitive error:nil];
NSArray* result = [regex matchesInString:test options:0 range:NSMakeRange(0, [test length])];
NSLog(#" %#", [result objectAtIndex:0]);
which puts out
<NSSimpleRegularExpressionCheckingResult: 0x105b17890>{0, 4}{<NSRegularExpression: 0x105b14700> test 0x1}
Thanks!!

[regex matchesInString...
gives you NSArray of NSTextCheckingResults.
Maybe you'd want to use firstMatchInSting:options:range:
It will give you NSTextCheckingResult, from which you can get range (NSRange) which you apply to your string with substringWithRange: method.
I hope you can understand. If not - I'll explain more carefully.
Nevertheless, read NSRegularExpression reference and NSTextCheckingResult reference

Okay. I'm making process. If I send 'regularExpression' to the element, it narrow the result down to
<NSRegularExpression: 0x106214700> test 0x1
I'm aware that this is the print-out of an object but I am still unsure how to isolate the text!

Related

How can I pull the year out of this NSString?

I have a number of NSStrings of movie titles like this:
#"Accepted (2006)"
#"Blade Runner (1982)"
#"(500) Days of Summer (2009)"
#"RoboCop (1987) - Criterion #23"
I am trying to get the four-digit numeric-only year that is always between ( and ) out of the title.
Whats the proper way to do this? NSRange? RegEx? Something else? Objective-C please, not Swift.
Use a lookaround based regex.
"(?<=\\()\\d{4}(?=\\))"
or
Use capturing group.
"\\((\\d{4})\\)"
Since (, ) are regex meta-characters, you need to escape those in-order to match the literal ( or ) symbols.
ie
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"\\((\\d{4})\\)" options:0 error:NULL];
NSString *str = #"Accepted (2006)";
NSTextCheckingResult *match = [regex firstMatchInString:str options:0 range:NSMakeRange(0, [str length])];
For this it is simpler to use the NSString method: rangeOfString:options: with the option NSRegularExpressionSearch with a look-behind and look-ahead based regex:
NSRange range = [test rangeOfString:#"(?<=\\()\\d{4}(?=\\))" options:NSRegularExpressionSearch];
NSString *found = [test substringWithRange:range];
NSLog(#"found: %#", found);
Output:
found: 2006
For more information see the ICU User Guide: Regular Expressions

NSRegularExpression get only the regex

i have a problem and i don't undestand how to do this ( after 6hours or googling)
i'have a string named "filename" containt this text :"Aachen-Merzbrück EDKA\r\r\nVerkehr"
i want to use regex to only get this part "Aachen-Merzbrück EDKA" but i cant....
here my code :
NSString *expression = #"\\w+\\s[A-Z]{4}";
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:expression options:NSRegularExpressionCaseInsensitive error:&error];
NSString *noAirportString = [regex stringByReplacingMatchesInString:filename options:0 range:NSMakeRange(0, [filename length]) withTemplate:#""];
EDIT :
this one work good :
\S+\s+[A-Z]{4}
but now, how to get only this "Aachen-Merzbrück" EDKA from "Aachen-Merzbrück EDKA\r\r\nVerkehr"
my regex with NSRegularExpression return me the same string ....
A couple of issues in your question:
No need to match city name characters - there are always weird ones around (hyphens, apostrophes, etc.) You can just match the first "line" in your text with a test for the ICAO code as an extra security.
Using stringByReplacingMatchesInString: you actually remove the airport name (and ICAO code) that you want keep.
stringByReplacingMatchesInString: is a hacky (because it deletes things, so you need to make your regexes "negative") shortcut that sometimes works (I use it myself) but which risks confusing things - and future readers.
Having said that, a few changes will fix it:
NSString *filename = #"Aachen-Merzbrück EDKA\r\r\nVerkehr";
// Match anything from the beginning of the line up to a space and 4 upper case letters.
NSString *expression = #"^.+\\s[A-Z]{4}$";
NSError *error = NULL;
//Make sure ^ and $ match line endings,
//and make it case sensitive (the default) to explicitly
//match the 4 upper case characters of the ICAO code
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:expression options:NSRegularExpressionAnchorsMatchLines error:&error];
NSArray *matches = [regex matchesInString:filename
options:0
range:NSMakeRange(0, [filename length])];
// Check that there _is_ a match before you continue
if (matches.count == 0) {
// Error
}
NSRange airportNameRange = [[matches objectAtIndex: 0] range];
NSString *airportString = [filename substringWithRange: airportNameRange];
Thanks it's good working, but i use this one, it's work better in my case :
NSString *expression = #"\\S+\\s+[A-Z]{4}";

String search in objective-c

Given a string like this:
http://files.domain.com/8aa55fc4-3015-400e-80f5-390997b43cf9/c07cb0d2-b7d7-4bfd-b0c3-6f43571e3c29-MyFile.jpg
I need to just locate the string "MyFile", and also tell what kind of image it is (.jpg or .png). How can I accomplish this?
The only thing I can think of is to search backward for the first four characters to get the file extension, then keep searching backward until I find the first hyphen, and assume the file name itself doesn't have any hyphens. But I don't know how to do that. Is there a better way?
Use NSRegularExpression to search for the file name. The search pattern really depends on what you know about the file name. If the "random" numbers and characters before MyFile has a known format, you could take that into account. My proposal below assumes that the file name doesn't contain any minus signs.
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:#"-([:alnum:]*)\\.(jpg|png)$"
options:NSRegularExpressionSearch
error:nil];
// Get the match between the first brackets.
NSTextCheckingResult *match = [regex firstMatchInString:string options:0
range:NSMakeRange(0, [string length])];
NSRange matchRange = [match rangeAtIndex:1];
NSString *fileName = [string substringWithRange:matchRange];
NSLog(#"Filename: %#", fileName);
// Get the extension with a simple NSString method.
NSString *extension = [string pathExtension];
NSLog(#"Extension: %#", extension);
[myString lastPathComponent] will get the filename.
[myString pathExtension] will get the extension.
To get the suffix of the filename, I think you'll have to roll your own parse. Is it always the string after the last dash and before the extension?
If so, here's an idea:
- (NSString *)lastLittleBitOfTheFilenameFrom:(NSString *)filename {
NSInteger fnStart = [filename rangeOfString:#"-" options:NSBackwardsSearch].location + 1;
NSInteger fnEnd = [filename rangeOfString:#"." options:NSBackwardsSearch].location;
// might need some error checks here depending on what you expect in the original url
NSInteger length = fnEnd - fnStart;
return [filename substringWithRange:NSMakeRange(fnStart, length)];
}
Or, thanks to #Chuck ...
// even more sensitive to unexpected input, but nice and tiny ...
- (NSString *)lastLittleBitOfTheFilenameFrom:(NSString *)filename {
NSString *nameExt = [[filename componentsSeparatedByString:#"-"] lastObject];
return [[nameExt componentsSeparatedByString:#"."] objectAtIndex:0];
}
If you have the string in an NSString object, or create it from that string, you may use the rangeOfString method to acomplish both.
See https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html for more details.

Find and replace in big files with Objective C, counting the number of replacements

I need to perform a find and replace (with regular expression) within a file using objective C.
My current solution is like this:
NSString *string = [NSString stringWithContentsOfFile:sourceFile encoding:NSStringEncodingConversionAllowLossy error:nil];
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:[toFind stringValue] options:NSRegularExpressionCaseInsensitive error:&error];
NSString *modifiedString = [regex stringByReplacingMatchesInString:string options:0 range:NSMakeRange(0, [string length]) withTemplate:[toReplace stringValue]];
[modifiedString writeToFile:sourceFile atomically:YES]
There are 2 problems with this solution:
1 - I can't get the number of occurrences replaced
2 - I think this is not really fast when loading files of nearly 300MB, because i'm loading the entire file into memory as a string.
How can i get the count of replacements made, and optimise my solution to have good performances even with big files?
Thanks in advance
numberOfMatchesInString called before you replace the matches will let you know how many times an occurrence will be replaced. Instead of loading the entire file into memory, do it piecemeal and keep a counter that you add the results of numberOfMatchesInString to.

stringByReplacingOccurrencesOfString Regular Expression

I'm developing a Mac app and I'm trying to replace use NSString's stringByReplacingOccurrencesOfString. I'm doing something like:
NSString *new = [s stringByReplacingOccurrencesOfString:#"(special-tag)*.*</body" withString:html];
On an NSString. But whenever I try to use this function with a regular expression it seems to break. Is there something I'm missing? I found a few external regex libraries, but I'd rather use something built in that has similar functionality.
Any advice? Thanks in advance! EDIT - I know why it's breaking, I need help figuring out how to do an NSString replace with regular expressions
As the name suggest stringByReplacingOccurrencesOfString OccurrencesOfString it's a string not a RegEx. So it will replace your string rather than your RegEx.
-----------Edited-----------------
I haven't used regex before hope this will give you the idea
NSString *string = #"this is your string";
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"\\b(a|b)(c|d)\\b" options:NSRegularExpressionCaseInsensitive error:&error];
NSString *modifiedString = [regex stringByReplacingMatchesInString:string options:0 range:NSMakeRange(0, [string length]) withTemplate:#"$2$1"];
Here is the NSRegularExpression Class Reference
Take a look at the NSRegularExpression class. It sounds like the -stringByReplacingMatchesInString:options:range:withTemplate: method will fit your needs. You might also like –replaceMatchesInString:options:range:withTemplate:.