Create Regular Expression for specified string in objective c - ios

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
)

Related

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.

Check if there is a word after a word (NSSTRING)

I have a fun little tricky problem. So I need to create an if statement that can detect if there is a word after a word in an array
so my code is
NSArray *words = [texfield.text componentsSeparatedByString:#" "];
int index = [words indexOfObject:#"string"];
I am not sure if I have to do something like
NSString*needle=words[index+1];
if (needle isEqualto #"") {
//There is a word after #"string";
}
What should I do?
How can I determine is there is a word after #"string"?
I appreciate all the help!! :)
Yeah, you have to:
NSArray *words = [texfield.text componentsSeparatedByString:#" "];
NSInteger index = [words indexOfObject:#"string"];
NSInteger afterIndex = index+1;
if(afterIndex<words.count) {
NSString *needle = words[index+1];
if (needle isEqualToString #"") {
//do something
}
}
NSString *yourString = #"string stackoverflow word after string regex";
NSRange yourStringRange = NSMakeRange(0, [yourString length]);
NSString *pattern = #"string\\s*([^\\s]*)";
NSError *error = nil;
NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern: pattern options:0 error:&error];
NSArray* matches = [regex matchesInString:yourString options:0 range: yourStringRange];
for (NSTextCheckingResult* match in matches) {
NSRange rangeForMatch = [match rangeAtIndex:1];
NSLog(#"word after STRING: %#", [yourString substringWithRange:rangeForMatch]);
}
Output:
word after STRING: stackoverflow
word after STRING: regex
Method componentsSeparatedByString: will give all components separated by input NSString.
Your eg. NSArray *words = [texfield.text componentsSeparatedByString:#" "];
will have all string separated by " ". So just check if any
NSInteger afterIndex = index+1;
if(afterIndex<words.count) if Yes, you have NSStringavailable.

Finding word in NSString and checking before and after character this word?

How to find word in NSString and check characters before and after this word?
"This pattern has two parts separated by the"
How to find tern and how to check the character before and after
Before word character:"t"
After word character:" "
You can use NSScanner to get indexes of these two characters.
Example:
NSString *string = #"tern";
NSScanner *scanner = [[NSScanner alloc] initWithString:#"This pattern has two parts separated by the"];
[scanner scanUpToString:string intoString:nil];
NSUInteger indexOfChar1 = scanner.scanLocation - 1;
NSUInteger indexOfChar2 = scanner.scanLocation + string.length;
You can also use a rangeOfString method:
Example:
NSRange range = [sourceString rangeOfString:stringToLookFor];
NSUInteger indexOfChar1 = range.location - 1;
NSUInteger indexOfChar2 = range.location +range.length + 1;
Then, when you have indexes, getting the characters is easy:
NSString *firstCharacter = [sourceString substringWithRange:NSMakeRange(indexOfChar1, 1)];
NSString *secondCharacter = [sourceString substringWithRange:NSMakeRange(indexOfChar2, 1)];
Hope this helps.
Here is an implementation using Regular Expressions
NSString *testString= #"This pattern has two parts separated by the";
NSString *regexString = #"(.)(tern)(.)";
NSRegularExpression* exp = [NSRegularExpression
regularExpressionWithPattern:regexString
options:NSRegularExpressionSearch error:&error];
if (error) {
NSLog(#"%#", error);
} else {
NSTextCheckingResult* result = [exp firstMatchInString:testString options:0 range:NSMakeRange(0, [testString length] ) ];
if (result) {
NSRange groupOne = [result rangeAtIndex:1]; // 0 is the WHOLE string.
NSRange groupTwo = [result rangeAtIndex:2];
NSRange groupThree = [result rangeAtIndex:3];
NSLog(#"[%#][%#][%#]",
[testString substringWithRange:groupOne],
[testString substringWithRange:groupTwo],
[testString substringWithRange:groupThree] );
}
}
Results:
[t][tern][ ]
Its better to get pre and post character in NSString to avoid handling of unicode characters.
NSString * testString = #"This pattern has two parts separated by the";
NSString * preString;
NSString * postString;
NSUInteger maxRange;
NSRange range = [testString rangeOfString:#"tern"];
if(range.location == NSNotFound){
NSLog(#"Not found");
return;
}
if (range.location==0) {
preString=nil;
}
else{
preString = [testString substringWithRange:NSMakeRange(range.location-1,1)];
}
maxRange = NSMaxRange(range);
if ( maxRange >=testString.length ) {
postString = nil;
}
else{
postString = [testString substringWithRange:NSMakeRange(range.location+range.length, 1)];
}

Truncate string containing emoji or unicode characters at word or character boundaries

How can I truncate a string at a given length without annihilating a unicode character that might be smack in the middle of my length? How can one determine the index of the beginning of a unicode character in a string so that I can avoid creating ugly strings. The square with half of an A visible is the location of another emoji character which has been truncated.
-(NSMutableAttributedString*)constructStatusAttributedStringWithRange:(CFRange)range
NSString *original = [_postDictionay objectForKey:#"message"];
NSMutableString *truncated = [NSMutableString string];
NSArray *components = [original componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
for(int x=0; x<[components count]; x++)
{
//If the truncated string is still shorter then the range desired. (leave space for ...)
if([truncated length]+[[components objectAtIndex:x] length]<range.length-3)
{
//Just checking if its the first word
if([truncated length]==0 && x==0)
{
//start off the string
[truncated appendString:[components objectAtIndex:0]];
}
else
{
//append a new word to the string
[truncated appendFormat:#" %#",[components objectAtIndex:x]];
}
}
else
{
x=[components count];
}
}
if([truncated length]==0 || [truncated length]< range.length-20)
{
truncated = [NSMutableString stringWithString:[original substringWithRange:NSMakeRange(range.location, range.length-3)]];
}
[truncated appendString:#"..."];
NSMutableAttributedString *statusString = [[NSMutableAttributedString alloc]initWithString:truncated];
[statusString addAttribute:(id)kCTFontAttributeName value:[StyleSingleton streamStatusFont] range:NSMakeRange(0, [statusString length])];
[statusString addAttribute:(id)kCTForegroundColorAttributeName value:(id)[StyleSingleton streamStatusColor].CGColor range:NSMakeRange(0, [statusString length])];
return statusString;
}
UPDATE Thanks to the answer, was able to use one simple function for my needs!
-(NSMutableAttributedString*)constructStatusAttributedStringWithRange:(CFRange)range
{
NSString *original = [_postDictionay objectForKey:#"message"];
NSMutableString *truncated = [NSMutableString stringWithString:[original substringWithRange:[original rangeOfComposedCharacterSequencesForRange:NSMakeRange(range.location, range.length-3)]]];
[truncated appendString:#"..."];
NSMutableAttributedString *statusString = [[NSMutableAttributedString alloc]initWithString:truncated];
[statusString addAttribute:(id)kCTFontAttributeName value:[StyleSingleton streamStatusFont] range:NSMakeRange(0, [statusString length])];
[statusString addAttribute:(id)kCTForegroundColorAttributeName value:(id)[StyleSingleton streamStatusColor].CGColor range:NSMakeRange(0, [statusString length])];
return statusString;
}
NSString has a method rangeOfComposedCharacterSequencesForRange that you can use to find the enclosing range in the string that contains only complete composed characters. For example
NSString *s = #"😄";
NSRange r = [s rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, 1)];
gives the range { 0, 2 } because the Emoji character is stored as two UTF-16 characters (surrogate pair) in the string.
Remark: You could also check if you can simplify your first loop by using
enumerateSubstringsInRange:options:usingBlock
with the NSStringEnumerationByWords option.
"truncate a string at a given length" <-- Do you mean length as in byte length or length as in number of characters? If the latter, then a simple substringToIndex: will suffice (check the bounds first though). If the former, then I'm afraid you'll have to do something like:
NSString *TruncateString(NSString *original, NSUInteger maxBytesToRead, NSStringEncoding targetEncoding) {
NSMutableString *truncatedString = [NSMutableString string];
NSUInteger bytesRead = 0;
NSUInteger charIdx = 0;
while (bytesRead < maxBytesToRead && charIdx < [original length]) {
NSString *character = [original substringWithRange:NSMakeRange(charIdx++, 1)];
bytesRead += [character lengthOfBytesUsingEncoding:targetEncoding];
if (bytesRead <= maxBytesToRead)
[truncatedString appendString:character];
}
return truncatedString;
}
EDIT: Your code can be rewritten as follows:
NSString *original = [_postDictionay objectForKey:#"message"];
NSArray *characters = [[original componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"SELF != ''"]];
NSArray *truncatedCharacters = [characters subarrayWithRange:range];
NSString *truncated = [NSString stringWithFormat:#"%#...", [truncatedCharacters componentsJoinedByString:#" "]];

Finding first letter in NSString and counting backwards

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];

Resources