0

The context is an IOS app. I would like to replace white spaces enclosed by brackets.

ex:

Toto "is Bill" should become Toto "is#Bill"

The weather is "bright and clear" should become The weather is "bright#and#clear"

I have made trials using the following code based on another post

NSString *pattern   = @"(?:(?<=^\")(\\s+))|(?:(?!^\")(\\s+)(?=.))|(?:(\\s+)(?=\"$))";  // (?:(?<=^")(\s+))|(?:(?!^")(\s+)(?=.))|(?:(\s+)(?="$))

NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:&error];

NSString *modifiedString = [regex stringByReplacingMatchesInString:string options:0 range:NSMakeRange(0, [string length]) withTemplate:@"#"];
NSLog(@"modified %@", modifiedString);

But this is not working right.

all spaces are replaced (Toto#"is#Bill")

I get the same result with just (?:(?!^")(\s+)(?=.))

I have made one on my own (?:\"\S*)(\s)(?:\S*) which is not ok neither

I will appreciate help on this! Thanks

lol74fr
  • 1
  • 2
  • You cannot do that with plain regex and string replacement pattern due to the fact the starting and trailing delimiters are equal. You need a callback to replace all spaces inside double quoted substrings and the only thing that is missing is whether your strings can contain escape sequences or if they can be matched with a mere `"[^"]+"` pattern. – Wiktor Stribiżew Jun 08 '18 at 16:41
  • My strings are string for a search text box. They won't contain escape sequences. – lol74fr Jun 08 '18 at 16:55
  • You need https://stackoverflow.com/questions/3957092. – Wiktor Stribiżew Jun 08 '18 at 18:18
  • This looks a little overkilling for such a simple matter but ok I will try this.thx – lol74fr Jun 08 '18 at 18:57
  • Sorry, that is Objective-C. In Python, it is a mere `re.sub(r'"[^"]+"', lambda x: x.group().replace(' ', '#'), s)`. In C#, `Regex.Replace(s, "\"[^\"]+\"", m => m.Value.Replace(" ", "#"))`. JS: `s.replace(/"[^"]+"/g, function(m) {return m.replace(/\s/g, '#');})` – Wiktor Stribiżew Jun 08 '18 at 18:59

1 Answers1

0

Here is a solution, I am using. This is probably not perfect but it works for my needs.

As Wiktor Stribiżew pointed out, my issue is that the first character and the last character of my pattern is the same character " He proposed me a solution which I find overkilling but that is needed because there is no callback function in Objective C.

As an alternative, here is how I have solved my issue (replacing spaces in quoted strings of a search box):

1) I add a space at the end of "the search box" string

NSString * searchstring1 = [searchString stringByAppendingString:@" "];

2) I use the following regex to replace the spaces (?:(?<="^"])(?=\w)|[^\S"])(?=[^"]"\s )

        NSString *pattern   = @"(?:(?<=\"^\"])(?=\\w)|[^\\S\"])(?=[^\"]*\"\\s* )";  // (?:(?<="^"])(?=\w)|[^\S"])(?=[^"]*"\s* )
        NSError *error = nil;
        NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:&error];
        NSString *searchstring2 = [regex stringByReplacingMatchesInString:searchstring1 options:0 range:NSMakeRange(0, [searchstring1 length]) withTemplate:@"xxx"];
        NSLog(@"modified %@", searchstring2);

3) I isolate all the tokens to search (separated by spaces)

NSMutableArray *words = (NSMutableArray *)[searchstring2 componentsSeparatedByString:@" "];

4) restore the spaces in the quoted strings and remove quotes

NSString *token;


    for(token in words)
    {

    token = [token stringByReplacingOccurrencesOfString:@"xxx" withString:@" "];
    token = [token stringByReplacingOccurrencesOfString:@"\"" withString:@""];
    NSLog(@"token %@\n", token);
    }

the following search string : Bill "the weather is bright" cool will give the following output

token Bill

token the weather is bright

token cool

Hope it helps others.

lol74fr
  • 1
  • 2