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];
Related
Original String is: This is a sentence with (noun) (verb) (adverb).
Original sentence has three occurrence of (). I need the last one intact but replace rest with #""
Required String: This is a sentence with (adverb).
I can do it with NSRange but I am looking for NSRegularExpression pattern.
Also which is more efficient, one with NSRange or the NSRegularExpression.
CODE
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"\\(.*?\\)" options:NSRegularExpressionCaseInsensitive error:NULL];
NSString *newString = [regex stringByReplacingMatchesInString:modify options:0 range:NSMakeRange(0, [modify length]) withTemplate:#""];
Output:: This is a sentence with
You can obtain the match ranges themselves and do the replacement manually, ignoring the last one.
NSMutableString* newString = [modify mutableCopy];
NSArray<NSTextCheckingResult*>* matches = [regex matchesInString:newString options:0 range:NSMakeRange(0, newString.length)];
if (matches.count >= 2)
{
// Enumerate backwards so that each replacement doesn't invalidate the other ranges
for (NSInteger i = matches.count - 2; i >= 0; i--)
{
NSTextCheckingResult* result = matches[i];
[newString replaceCharactersInRange:result.range withString:#""];
}
}
I'm trying to use NSRegularExpression to find multiple occurrences of substrings that are delimited by a pair of % characters, for example if I want to extract "%FirstOccurence%enter code here" as a substring from the following:
"stuff %FirstOccurence% more stuff"
Then I can do this:
NSString* const pattern = #"[%].+[%]";
NSRegularExpression* regex = [[NSRegularExpression alloc] initWithPattern:pattern
options:0
error:nil];
NSRange range = NSMakeRange(0, [testData length]);
NSTextCheckingResult *textCheckingResult = [regex firstMatchInString:testData options:0 range: range];
However if the string contains something like this:
"stuff %FirstOccurence% more stuff %Second Occurrence% yet more stuff"
Then my regex will match this: "%FirstOccurence% more stuff %Second Occurrence%" i.e. the NSTextCheckingResult will contain one range.
What should the regex/code be to make the NSTextCheckingResult contain two ranges of %FirstOccurence% and %Second Occurrence% rather than the one larger range?
It appears you want to be calling matchesInString:options:range: which returns all the matching results.
NSArray *matches = [regex matchesInString:string
options:0
range:NSMakeRange(0, [string length])];
See https://developer.apple.com/library/mac/documentation/Foundation/Reference/NSRegularExpression_Class/Reference/Reference.html#//apple_ref/doc/c_ref/NSRegularExpression
in objective-c I have a string as follows:
CAST(407704969.734560,
I want to extract the digits:
407704969.734560
The code I'm using is this one:
NSString *stringToCheck = #"CAST(407704969.734560,"
NSRange searchedRange = NSMakeRange(0, [stringToCheck length]);
NSString *pattern = #"(?<=CAST\\()(\\d+?.?\\d+?)(?=,)";
NSError *error = nil;
NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];
NSArray* matches = [regex matchesInString:stringToCheck options:0 range: searchedRange];
for (NSTextCheckingResult* match in matches) {
NSString* matchText = [stringToCheck substringWithRange:[match range]];
NSLog(#"match: %#", matchText);
}
I guess the problem is in the regex, seen that I can't find any tutorial about it.
You could try using following regex:
PATTERN
CAST\((\d+?\.?\d+?),
INPUT
CAST(407704969.734560,
OUTPUT
Match 1: CAST(407704969.734560,
Group 1: 407704969.734560
Or if you only need the digits try this:
PATTERN
(?<=CAST\()(\d+?\.?\d+?)(?=,)
INPUT
CAST(407704969.734560,
OUTPUT
Match 1: 407704969.734560
And here you have not long but really nice regex tutorial:
www.codeproject.com
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}";
I need to calculate word length of string for the certain known language, which has some letter sequence, to count it as 1 letter. Say letters "ao" is one letter. How can I achieve this?
One idea would be to replace each occurrence of the letter sequences by a single character and
count the length of the result:
NSString *string = #"Hello world";
NSMutableString *tmp = [string mutableCopy];
NSArray *sequences = #[#"ll", #"wo"];
for (NSString *seq in sequences) {
[tmp replaceOccurrencesOfString:seq
withString:#"."
options:NSCaseInsensitiveSearch
range:NSMakeRange(0, [tmp length])];
}
// tmp is "He.o .rld" now
NSUInteger length = [tmp length];
Remark: length does not count "composed characters" as a single character.
If that is an issue, you have to use enumerateSubstringsInRange:options:usingBlock:
with the NSStringEnumerationByComposedCharacterSequences option to count the
characters correctly. This applies for example to all "UTF-16" surrogate pairs (e.g. Emojis). It might apply to other characters such as Hangul characters as well,
I am not sure about that right now.
ADDED: The following method uses regular expressions and should work as well.
The advantage might be that no temporary strings are created. But one should
measure which method is really faster.
NSString *string = #"Hello world";
NSString *pattern = #"ll|wo|.";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern
options:NSRegularExpressionCaseInsensitive
error:NULL];
NSUInteger length = [regex numberOfMatchesInString:string
options:0
range:NSMakeRange(0, [string length])];
NSLog(#"length = %d", length);