1

I'm pretty new to using regex in iOS, and I'm experimenting with it. I'm struggling to find a solution to the problem I have. I apologize in advance if this has been answered before or I'm just missing something really obvious and/or using the wrong tool to accomplish my goal.

I have a string that the user will enter in a textfield. How do I then change that to correct a spelling of a word that is contained inside the string?

NSString *userstring = @"Jon Travalta";
NSError *error = NULL;
NSString *modstring = @"";

NSRegularExpression *regex = [[NSRegularExpression alloc]init];
regex = [NSRegularExpression regularExpressionWithPattern:@"(Jon|Johnathan|Jonathen|John)\\s(Travalta|Travalte|Travelta|Travolta)" options:NSRegularExpressionCaseInsensitive error:&error];

modstring = [regex stringByReplacingMatchesInString:userstring options:0 range:NSMakeRange(0,[userstring length]) withTemplate:@"John Travolta"];

That works and corrects the string fine, but let's say the string is something else. I want to keep that regex active to check the string if it contains any of those elements to correct it.

So let's say the string is set, before the above check, to "Anthony Hopkin". I would then also use another regexwithpattern to check the string to correct that one with the correct spelling of the name.

regex = [NSRegularExpression regularExpressionWithPattern:@"(Anthony|Antony|Tony|)\\s(Hopkin|Hapkin|Hopkins)" options:NSRegularExpressionCaseInsensitive error:&error];

modstring = [regex stringByReplacingMatchesInString:userstring options:0 range:NSMakeRange(0,[userstring length]) withTemplate:@"Anthony Hopkins"];

This will replace the string with Anthony Hopkins, even if it's the first string.

If I do a different alloc of NSRegularExpression and different stringByReplacingMatchesInString, it just doesn't do anything and the string stays what it was to begin with.

6
  • Are you asking if a single expression can match all possible names. The answer is that it can, by combining them into 1. However, the replacement would have to know which one matched. This would require a dynamic string as opposed to a static string. Commented Dec 16, 2015 at 17:45
  • @sln i agree a single expression is probably the way i will go with it, But how would i use a dynamic string to check which one matched to choose which replacement would be called. Could you give me an example please? i would be very grateful Commented Dec 17, 2015 at 11:08
  • the easiest way of eliminating typos is generating soundex values, it might work in your case as well on. Commented Dec 17, 2015 at 12:13
  • Not sure I understand your issue. Can you give the actual code you use when you have the issue, what the output is, and what you expect it to be? Commented Dec 17, 2015 at 12:17
  • @jcaron so if i do this: regexVal = [NSRegularExpression regularExpressionWithPattern:@"(Jon|Johnathan|Jonathan|John)\\s(Travalta|Travalte|Travolta) | (Antony|Anthony|Tony)\\s(Hopkin|Hapkin|Hopkins)" options:NSRegularExpressionCaseInsensitive error:&error]; then i want to replace any of the spelling mistake of the first expression to @"Jon Travolta" and the second one to @"Anthony Hopkins" though if i use StringByReplacingMatchesInString it'll replace both with whatever i set the last Template to. so it will even replace John Travalta with Anthony Hopkins Commented Dec 17, 2015 at 13:48

2 Answers 2

2

Regular expressions are not the right tool for spell checking.

In your question you want to make multiple replacements based on regular expressions. For clarity I'd just iterate though your list of possible corrections applying them one at a time.

-(NSString*) naiiveSpellCheckString:(NSString*) s {

  NSDictionary* corrections = @{
                                @"Travolta": @"Travalta|Travalte|Travelta|Travolta",
                                @"John": @"Jon|Johnathan|Jonathen",
                                @"Anthony":@"Anthoni|Antony|Tony",
                                @"Hopkins": @"Hopkin|Hapkin",
                                };

  for (NSString* key in corrections.keyEnumerator) {

      NSError* error;
      NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:[corrections objectForKey:key]
                                    options:NSRegularExpressionCaseInsensitive
                                    error:&error];

      NSAssert1(!error, @"Error parsing regex %@", [corrections objectForKey:key]);

      s = [regex stringByReplacingMatchesInString:s
                                          options:0
                                            range:NSMakeRange(0, s.length) withTemplate:key];

  }

  return s;
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! Works like a treat. Exactly what i wanted. Appreciated
0

I ran into the same thing and I built a method that will build the expression for me from an array of stings.

NSArray* itemsArray = [@“Jon”, @“Johnathan”, @“Johnathen”, @“John”];

NSMutableString* builtString = @“”;

for (NSString* aItem in itemsArray) {
    NSString* formatString;
    if (![builtSting hasSuffix:@“| “] ) {
        formatString = [NSSting stringWithFormat:@“%@”, aItem];
    }
    else {
        formatString = [NSSting stringWithFormat:@“ | %@”, aItem];
    }
[builtSting stringByAppendingString:formatString];
}

———————————-

add any prefixes or suffixes to complete the expression

repeat for last names group

combine the groups and add any additional regex prefixes Or suffixes.

It may be easier to just execute the search on each name, rather than combining a super large multi first names / last names one. (And easier to debug)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.