Finding first letter in NSString and counting backwards - ios

I'm new to IOS, and was looking for some guidance.
I have a long NSString that I'm parsing out. The beginning may have a few characters of garbage (can be any non-letter character) then 11 digits or spaces, then a single letter (A-Z). I need to get the location of the letter, and get the substring that is 11 characters behind the letter to 1 character behind the letter.
Can anyone give me some guidance on how to do that?
Example: '!!2553072 C'
and I want : '53072 '

You can accomplish this with the regex pattern: (.{11})\b[A-Z]\b
The (.{11}) will grab any 11 characters and the \b[A-Z]\b will look for a single character on a word boundary, meaning it will be surrounded by spaces or at the end of the string. If characters can follow the C in your example then remove the last \b. This can be accomplished in Objective-C like so:
NSError *error;
NSString *example = #"!!2553072 C";
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:#"(.{11})\\b[A-Z]\\b"
options:NSRegularExpressionCaseInsensitive
error:&error];
if(!regex)
{
//handle error
}
NSTextCheckingResult *match = [regex firstMatchInString:example
options:0
range:NSMakeRange(0, [example length])];
if(match)
{
NSLog(#"match: %#", [example substringWithRange:[match rangeAtIndex:1]]);
}

There may be a more elegant way to do this involving regular expressions or some Objective-C wizardry, but here's a straightforward solution (personally tested).
-(NSString *)getStringContent:(NSString *)input
{
NSString *substr = nil;
NSRange singleLetter = [input rangeOfCharacterFromSet:[NSCharacterSet letterCharacterSet]];
if(singleLetter.location != NSNotFound)
{
NSInteger startIndex = singleLetter.location - 11;
NSRange substringRange = NSMakeRange(start, 11);
substr = [tester substringWithRange:substringRange];
}
return substr;
}

You can use NSCharacterSets to split up the string, then take the first remaining component (consisting of your garbage and digits) and get a substring of that. For example (not compiled, not tested):
- (NSString *)parseString:(NSString *)myString {
NSCharacterSet *letters = [NSCharacterSet letterCharacterSet];
NSArray *components = [myString componentsSeparatedByCharactersInSet:letters];
assert(components.count > 0);
NSString *prefix = components[0]; // assuming relatively new Xcode
return [prefix substringFromIndex:(prefix.length - 11)];
}

//to get rid of all non-Digits in a NSString
NSString *customerphone = CustomerPhone.text;
int phonelength = [customerphone length];
NSRange customersearchRange = NSMakeRange(0, phonelength);
for (int i =0; i < phonelength;i++)
{
const unichar c = [customerphone characterAtIndex:i];
NSString* onechar = [NSString stringWithCharacters:&c length:1];
if(!isdigit(c))
{
customerphone = [customerphone stringByReplacingOccurrencesOfString:onechar withString:#"*" options:0 range:customersearchRange];
}
}
NSString *PhoneAllNumbers = [customerphone stringByReplacingOccurrencesOfString:#"*" withString:#"" options:0 range:customersearchRange];

Related

Objective C - NSRegularExpression with specific substring

I have an NSString which I am checking if there is an NSLog and then I comment it out.
I am using NSRegularExpression and then looping through result.
The code:
-(NSString*)commentNSLogFromLine:(NSString*)lineStr {
NSString *regexStr =#"NSLog\\(.*\\)[\\s]*\\;";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regexStr options:NSRegularExpressionCaseInsensitive error:nil];
NSArray *arrayOfAllMatches = [regex matchesInString:lineStr options:0 range:NSMakeRange(0, [lineStr length])];
NSMutableString *mutStr = [[NSMutableString alloc]initWithString:lineStr];
for (NSTextCheckingResult *textCheck in arrayOfAllMatches) {
if (textCheck) {
NSRange matchRange = [textCheck range];
NSString *strToReplace = [lineStr substringWithRange:matchRange];
NSString *commentedStr = [NSString stringWithFormat:#"/*%#*/",[lineStr substringWithRange:matchRange]];
[mutStr replaceOccurrencesOfString:strToReplace withString:commentedStr options:NSCaseInsensitiveSearch range:matchRange];
NSRange rOriginal = [mutStr rangeOfString:#"NSLog("];
if (NSNotFound != rOriginal.location) {
[mutStr replaceOccurrencesOfString:#"NSLog(" withString:#"DSLog(" options:NSCaseInsensitiveSearch range:rOriginal];
}
}
}
return [NSString stringWithString:mutStr];
}
The problem is with the test case:
NSString *str = #"NSLog(#"A string"); NSLog(#"A string2")"
Instead of returning "/*DSLog(#"A string");*/ /*DSLog(#"A string2")*/" it returns: "/*DSLog(#"A string"); NSLog(#"A string2")*/".
The issue is how the Objective-C handles the regular expression. I would expected 2 results in arrayOfAllMatches but instead that I am getting only one. Is there any way to ask Objective-C to stop on the first occurrence of ); ?
The problem is with the regular expression. You are searching for .* inside the parentheses, which causes it to include the first close parenthesis, continue through the second NSLog statement, and go all the way to the final close parentheses.
So what you want to do is something like this:
NSString *regexStr =#"NSLog\\([^\\)]*\\)[\\s]*\\;";
That tells it to include everything inside the parenthesis except for the ) character. Using that regex, I get two matches. (note that you omitted the final ; in your string sample).

How to add a character at start and end of every word in NSString

Suppose i have this:
NSString *temp=#"its me";
Now suppose i want ' " ' in start and end of every word, how can i achieve it to get the result like this:
"its" "me"
Do i have to use regular expressions?
If you have punctuation inside the string, splitting with a space might not be enough.
Use the word boundary \b: it matches both the leading and trailing word boundaries (that is, it will match an empty space right between word and non-word characters and also at the start/end of the string if followed/preceded with a word character.
NSError *error = nil;
NSString *myText = #"its me";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"\\b" options:NSRegularExpressionCaseInsensitive|NSRegularExpressionAnchorsMatchLines error:&error];
NSString *modifiedString = [regex stringByReplacingMatchesInString:myText options:0 range:NSMakeRange(0, [myText length]) withTemplate:#"\""];
NSLog(#"%#", modifiedString); // => "its" "me"
See the IDEONE demo
See more details on the regex syntax in Objective C here.
You can do something like,
NSString *str = #"its me";
NSMutableString *resultStr = [[NSMutableString alloc]init];
NSArray *arr = [str componentsSeparatedByString:#" "];
for (int i = 0; i < arr.count; i++) {
NSString *tempStr = [NSString stringWithFormat:#"\"%#\"",arr[i]];
resultStr = [resultStr stringByAppendingString:[NSString stringWithFormat:#"%# ",tempStr]];
}
NSLog(#"result string is : %#",resultStr);
Hope this will help :)

how to Find the end of the string while i know the start location of the string

I am stuck with strange problem.In my UI-textview i detail text,I want to highlight/color the certain line or paragraph started with specific word.So far i was able to find the location of the starting word but not able to find the end of the line and paragraph.Problem is that the new line (\n) is not recognize as i had already tried.
Can any one help me how to find the solution.Here the code
NSArray *matches = [regex matchesInString:self.textfiled.text options:0 range:NSMakeRange(0, self.textfiled.text.length)];
for (NSTextCheckingResult *match in matches) {
NSString *string =self.textfiled.text;
NSRange wordRange = [match rangeAtIndex:0];
unsigned long lock=0;
unsigned long i=0;
[stirng replaceCharactersInRange:wordRange withString:#"\nདཔེར་ན། "];
unsigned long length = [string length];
unsigned long paraStart = wordRange.length,paraEnd =0,contentsEnd =0;
NSMutableArray *array = [NSMutableArray array];
NSRange currentRange;
for( i=0;![[self.textfiled.text substringWithRange:NSMakeRange(wordRange.location+i+1,1)] isEqualToString:#" "];i++)
{
NSLog(#"\n %lu------------>",i);
lock=i;
}
NSLog(#"\n %lu------------>",lock);
NSRange range = NSMakeRange(wordRange.location,wordRange.length);
NSString *str = [self.textfiled.text substringWithRange:range];
NSLog(#"\n%lu--------",[str length]);
NSRange wordRanged1 = NSMakeRange(wordRange.location, 7+7);
[stirng addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithRed:22/255.0f green:123/225.0f blue:108/255.0f alpha:1.0f] range:wordRanged1];
}
Following the inspiration of your code, I created a similar solution that locates the line end and paragraph end given the starting character of a matched word. Paragraphs are separated by \n\n and lines are ended with \n. The end of your text field will likely need to be handled as a special case.
Note that the .* will match to the end of the line with the given regular expression options. The paragraph ends are located by finding a matching \n\n.
self.myText = #"hello world\n\nthis is a test\nsingle line\n\n";
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"hello.*"
options:NSRegularExpressionCaseInsensitive
error:&error];
NSArray *matches = [regex matchesInString:self.myText options:0 range:NSMakeRange(0, self.myText.length)];
for (NSTextCheckingResult *match in matches) {
NSRange lineRange = [match rangeAtIndex:0];
NSLog(#"match start is %lu", lineRange.location);
NSLog(#"line end is %lu", lineRange.location + lineRange.length);
// Find paragraph ends:
NSInteger i = lineRange.location;
unichar lineSeparator = 0x2028;
while (i < self.myText.length - 1) {
// Case where string uses \n\n to denote a paragraph:
NSString *subString = [self.myText substringWithRange:NSMakeRange(i, 2)];
if ( [subString isEqualToString:#"\n\n"] ) {
NSLog(#"found paragraph end at %ld", (long)i);
}
// Case where text view uses line separator characters:
if ([subString characterAtIndex:0] == lineSeparator && [subString characterAtIndex:1] == lineSeparator) {
NSLog(#"found paragraph end at %ld", (long)i);
}
i++;
}
}
In my sample, I get
match start is 0
line end is 11
found paragraph end at 11
found paragraph end at 39
I’ve created a little guide to visualize the results:
hello world++this is a test+single line++
01234567891111111111222222222233333333334
0123456789012345678901234567890
This could be adapted to a standalone function that should provide the kind of results you are seeking.

Create Regular Expression for specified string in objective c

My NSString like below
#"[o=uid=35=] hghk\u00c2\u00a0 [o=uid=30=] [o=uid=35=] cong."
I need to create regular expression which search numeric values (e.g in first square brackets there is 35 in second there is 30 like this) in between square parenthesis. How could i achieve this task. Is there any alternate way to search numeric values in between square parenthesis? Please help me to short resolve from this. your help would be appreciable.
Using NSRegularExpression,
NSString* strSource = #"[o=uid=35=] hghk\u00c2\u00a0 [o=uid=30=] [o=uid=35=] cong.";
NSError* errRegex = NULL;
NSRegularExpression* regex = [NSRegularExpression
regularExpressionWithPattern:#"uid=([0-9]+)"
options:NSRegularExpressionCaseInsensitive
error:&errRegex];
NSUInteger countMatches = [regex numberOfMatchesInString:strSource
options:0
range:NSMakeRange(0, [strSource length])];
NSLog(#"Number of Matches: %ld", (unsigned long)countMatches);
[regex enumerateMatchesInString:strSource options:0
range:NSMakeRange(0, [strSource length])
usingBlock:^(NSTextCheckingResult* match,
NSMatchingFlags flags, BOOL* stop) {
NSLog(#"Ranges: %ld", (unsigned long)[match numberOfRanges]);
NSString *matchFull = [strSource substringWithRange:[match range]];
NSLog(#"Match: %#", matchFull);
for (int i = 0; i < [match numberOfRanges]; i++) {
NSLog(#"\tRange %i: %#", i,
[strSource substringWithRange:[match rangeAtIndex:i]]);
}
}];
if (errRegex) {
NSLog(#"%#", errRegex);
}
http://regexpal.com/
use above link to check the expression
\b[0-9]+
to find all the integer values
([0-9])+
it works.
You can build a regular expression like this:
uid=([0-9]+)
This will find any numbers after "uid=" sequence in a string. The value of the number will be available in "match 1", since it is put in parentheses. You can try out this Regex interactively with http://rubular.com/.
if you just want numeric value then you can try this
NSString *mainString = #"[o=uid=35=] hghk\u00c2\u00a0 [o=uid=30=] [o=uid=35=] cong.";
NSArray *arr = [mainString componentsSeparatedByString:#"="];
for(int i=0;i<arr.count;i++)
{
NSString *newString = arr[i];
NSCharacterSet* notDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
if ([newString rangeOfCharacterFromSet:notDigits].location == NSNotFound)
{
NSLog(#"%#",newString);
// newString consists only of the digits 0 through 9
}
}
Here is my code,it works perfectly..we can check easily below array contains object(numbers between '[' and ']') or not without using any regex.
NSString *tmpTxt = #"[o=uid=35=] hghk\u00c2\u00a0 [o=uid=30=] [o=uid=35=] cong.";
NSString*splittxt=tmpTxt;
NSMutableArray*array=[[NSMutableArray alloc]init];
for (int i=0; i<i+1; i++) {
NSRange r1 = [splittxt rangeOfString:#"["];
NSRange r2 = [splittxt rangeOfString:#"]"];
NSRange rsub=NSMakeRange(r1.location + r1.length-1, r2.location - r1.location - r1.length+2);
if (rsub.length >2 ){
NSCharacterSet *AllowedChars = [[NSCharacterSet characterSetWithCharactersInString:#"1234567890"] invertedSet];
NSString*stringg=[splittxt substringWithRange:rsub];
stringg = [[stringg componentsSeparatedByCharactersInSet:AllowedChars] componentsJoinedByString:#""];
[array addObject:stringg];
}
else
{
break;
}
splittxt=[splittxt stringByReplacingCharactersInRange:rsub withString:#""];
}
NSLog(#"%#",array);
}
the array value is
(
35,
30,
35
)

iOS: extract substring of NSString in objective C

I have an NSString as:
"<a href='javascript:void(null)' onclick='handleCommandForAnchor(this, 10);return false;'>12321<\/a>"
I need to extract the 12321 near the end of the NSString from it and store.
First I tried
NSString *shipNumHtml=[mValues objectAtIndex:1];
NSInteger htmlLen=[shipNumHtml length];
NSString *shipNum=[[shipNumHtml substringFromIndex:htmlLen-12]substringToIndex:8];
But then I found out that number 12321 can be of variable length.
I can't find a method like java's indexOf() to find the '>' and '<' and then find substring with those indices. All the answers I've found on SO either know what substring to search for or know the location if the substring. Any help?
I don't usually advocate using Regular expressions for parsing HTML contents but it seems a regex matching >(\d+)< would to the job in this simple string.
Here is a simple example:
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#">(\\d+)<"
options:0
error:&error];
// Handle error != nil
NSTextCheckingResult *match = [regex firstMatchInString:string
options:0
range:NSMakeRange(0, [string length])];
if (match) {
NSRange matchRange = [match rangeAtIndex:1];
NSString *number = [string substringWithRange:matchRange]
NSLog(#"Number: %#", number);
}
As #HaneTV says, you can use the NSString method rangeOfString to search for substrings. Given that the characters ">" and "<" appear in multiple places in your string, so you might want to take a look at NSRegularExpression and/or NSScanner.
that may help on you a bit, I've just tested:
NSString *_string = #"<a href='javascript:void(null)' onclick='handleCommandForAnchor(this, 10);return false;'>12321</a>";
NSError *_error;
NSRegularExpression *_regExp = [NSRegularExpression regularExpressionWithPattern:#">(.*)<" options:NSRegularExpressionCaseInsensitive error:&_error];
NSArray *_matchesInString = [_regExp matchesInString:_string options:NSMatchingReportCompletion range:NSMakeRange(0, _string.length)];
[_matchesInString enumerateObjectsUsingBlock:^(NSTextCheckingResult * result, NSUInteger idx, BOOL *stop) {
for (int i = 0; i < result.numberOfRanges; i++) {
NSString *_match = [_string substringWithRange:[result rangeAtIndex:i]];
NSLog(#"%#", _match);
}
}];

Resources