NSRegularExpression get only the regex - objective-c

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}";

Related

Regex number of matches is always zero

I want to check a UITextField text with a format like "G12-123456".
Rules are simple;
First character must be upper case letter.
The 2nd and 3rd must be number.
Fourth must be "-" character.
The last six must be only numbers.
Below code not work, number of matches always returns zero.
I also tried regex as "[A-Z0-9]{3}-[0-9]{6}"
NSString * myRegex = #"[A-Z][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9]";
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:myRegex
options:NSRegularExpressionCaseInsensitive
error:&error];
NSUInteger numberOfMatches = [regex numberOfMatchesInString:string
options:NSMatchingReportProgress
range:NSMakeRange(0, [string length])];
This one works with same code [^a-zA-Z0-9] -> Check whether an NSString contains a special character and a digit.
Any help would be appreciated.
First of all basically your code is supposed to work.
However both options are nonsensical. If you want to check for uppercase letter you must not pass NSRegularExpressionCaseInsensitive and NSMatchingReportProgress affects only the block based API.
In both cases pass 0.
The pattern can be written more efficient
NSString *myRegex = #"[A-Z]\\d{2}-\\d{6}";
NSError *error;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:myRegex
options:0
error:&error];
if {error) {
NSLog(#"%#", error);
} else {
NSUInteger numberOfMatches = [regex numberOfMatchesInString:string
options:0
range:NSMakeRange(0, [string length])];
NSLog(#"%lu", numberOfMatches);
}
If the regex must match the entire string add the start - end anchors.
NSString *myRegex = #"^[A-Z]\\d(2)-\\d{6}$";
If numberOfMatches is zero please check if the hyphen character is the standard one (ASCII 45, hex 0x2D).

Objective C - Split string into array

How would I do this? I'm new to Objective-C but I can't find anything that would help me do this.
NSArray *splitLine = [currentLine componentsSeparatedByString:#":%#",notNumber];
Where notNumber is a string that represents anything that isn't a number. So I want to separate a string where there are colons separated by strings that aren't numbers. (I want to avoid splitting at times i.e. 3:00pm, but split at iCal parameters like DESCRIPTION: and LOCATION:.)
You can do this in several steps, like this. I have not compiled this code, but it should at least give you an idea of what to do.
1) Create a regex object to match your separators:
NSString *regexString = #"DESCRIPTION:\s|LOCATION:\s"; // or whatever makes sense for your scenario
NSRegularExpression *regex =
[NSRegularExpression regularExpressionWithPattern:regexString
options:NSRegularExpressionCaseInsensitive
error:nil];
2) Replace all the different separators matching your regex with just one separator:
NSRange range = NSMakeRange(0, string.length);
NSString *string2 = [regex stringByReplacingMatchesInString:string
options:0
range:range
withTemplate:#"SEPARATOR"];
3) Split the string!
NSArray *elements = [string2 componentsSeparatedByString:#"SEPARATOR"];
Shortest solution for splitting string.
NSString *str = #"Please split me to form array of words";
NSArray *wordsArray = [str componentsSeparatedByString:#" "];
You can use regular expressions!
Using the pattern (I believe this is the core of your question):
pattern = #"(?<=[^0-9]):(?=[^0-9])"
This pattern will only match ':' symbols not surrounded by numbers.
Then replace with a dummy value that won't show in your data
dummy = #"NEVERSEETHIS"
NSRegularExpressions *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:nil];
NSRange range = NSMakeRange(0, [string length])
NSString *modified= [regex replaceMatchesInString:yourString options:0 range:range withTemplate:dummy];
and finally, split
return [modified componentsSeparatedByString:dummy];

RegEx (replaceMatchesInString) does not work

Why does this RegEx with replaceMatchesInString return only "+" instead of "+123"?
NString *phoneNumberCleaned = [NSString stringWithFormat:#"++00123"];
NSString *strRegExPhoneNumberPrefixWrong = #"^([+0]*)\\d*$";
NSRegularExpression *regEx = [NSRegularExpression regularExpressionWithPattern:strRegEx options:0 error:nil];
[regEx replaceMatchesInString:phoneNumberCleaned options:0 range:NSMakeRange(0, [phoneNumberCleaned length]) withTemplate:#"+"];
return phoneNumberCleaned;
Thanks
NSString *string = #"++00123";
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:#"^[+0]+(?=\\d*)"
options:NSRegularExpressionCaseInsensitive
error:&error];
NSString *modifiedString = [regex
stringByReplacingMatchesInString:string
options:0
range:NSMakeRange(0, [string length])
withTemplate:#"+"];
return modifiedString;
The problem with your Regex was that ^([+0]*)\\d*$ is also matching the \d* which means, that it also gets replaced (you'd think that it would only replace your capture group, but evidently that isn't so). So you were essentialy replacing any string that matches the above pattern (which was including any trailing numbers), which in your case was the entire number.
What I used in my answer is called a positive lookahead.
^[+0]+(?=\\d*)$
The lookahead basically means that you're looking for zero or more + or 0 that are followed by zero or more digits EXCLUDING the digits from the match. So you only replace the zeroes and pluses, not the digits following them.

Why is my NSRegularExpression pattern not working?

I have the following string:
NSString *string = #"she seemed \x3cem\x3ereluctant\x3c/em\x3e to discuss the matter";
I want the final string to be: "she seemed reluctant to discuss the matter"
I have the following pattern:
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"/\\x[0-9a-f]{2}/"
options:NSRegularExpressionCaseInsensitive
error:&error];
NSArray *matches = [regex matchesInString:string options:0 range:NSMakeRange(0, [string length])];
for (NSTextCheckingResult *match in matches) {
NSRange matchRange = [match range];
NSLog(#"%#", NSStringFromRange(matchRange));
}
However, I get an error saying the pattern is invalid. What am I doing wrong?
The pattern you need is:
#"\\\\x[0-9a-f]{2}"
The backslash is special to both Obj-C and the RE parser - so you need to create an Obj-C string with two \'s so the RE parser can then end up with one.
Also there are no open/close delimiters in the string - you're thinking of another programming language there!
You can save yourself some regex troubles by using the NSString method
stringByReplacingOccurrencesOfString:withString:
Or
stringByReplacingOccurrencesOfString:withString:options:range:

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.