1

Can you please suggest me regular expression which will only match '&' from string but not '&&'.

E.g. Input String

s1 = "STRING1 && STRING2 & STRING3 AND STRING4";

I'm splitting input string with function -

String[] param = s1.split('&'); or s1.split('&(?!&&)');

Result after split should be -

param[1] = STRING1 && STRING2  
param[2] = STRING3 AND STRING4

Thank you for your replies.

Dev

Enigma
  • 749
  • 1
  • 13
  • 35

3 Answers3

2

You can make use of lookaround in regex here

(?<!&)&(?!&)

The above regex matches an & neither preceded nor followed by another &.

Ravi K Thapliyal
  • 51,095
  • 9
  • 76
  • 89
  • in addition to this, I have one more doubt what if input string comes as ---> STRING1 &&&STRING2 & STRING3 in this case this regex is failing at my site. Can you please help me here ? – Enigma Sep 16 '13 at 09:35
  • @DevendraW, it works fine at my end. The string gets split at `&` as `STRING1 &&& STRING2 | STRING3`. – Ravi K Thapliyal Sep 16 '13 at 12:26
  • Input String - STRING1 &&& STRING2 | STRING3 should be split as 1. String1 && 2.String2 | String3 It's not working because from &&& which '&' it selects to split ? I want 3rd & to be used for splitting. Do you have any other regex suggestion ? – Enigma Sep 17 '13 at 04:20
  • Got it - regex should be - ((?<=&&)&(?!&))|((?<!&)&(?!&)) – Enigma Sep 17 '13 at 04:49
  • @DevendraW, I meant an input `STRING1 &&& STRING2 & STRING3` would be split as (1) `STRING1 &&& STRING2 ` and (2) ` STRING3`. (The `|` was used just to show the different parts.) I was assuming `&&&` is coming as part of your data and isn't an operator to split on. I'm not sure what exactly is that you're parsing here so can't recommend a better regex at the moment. – Ravi K Thapliyal Sep 17 '13 at 06:07
  • It's been fixed now. Thank you very much for your earlier suggestion. I was parsing - STRING1 &&& STRING2 | STRING3 so that it should split on & - and should be split as 1. String1 && 2.String2 | String3 which i achieved with above posted regex. – Enigma Sep 17 '13 at 07:11
1

You can use this pattern as well:

[^&]&[^&]

and a call to some language specific SPLIT function should do the job.

If this is for iOS platform, try this example in a separate app:

NSString *string = @"STRING1 && STRING2 & STRING3 AND STRING4"; //[NSString stringWithFormat:@"%@", @""];

NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"[^&]&[^&]"
                                                                       options:NSRegularExpressionCaseInsensitive
                                                                         error:&error];

NSUInteger numberOfMatches = [regex numberOfMatchesInString:string
                                                    options:0
                                                      range:NSMakeRange(0, [string length])];
NSLog(@"numberOfMatches : %d", numberOfMatches);
NSArray *matches = [regex matchesInString:string
                                  options:0
                                    range:NSMakeRange(0, [string length])];

for (NSTextCheckingResult *match in matches) // adjust loop per your criteria
{
    NSRange matchRange = [match range];

    // Pick the separator
    NSLog(@"::::%@", [string substringWithRange:matchRange]);

    // Splitted string array
    NSArray *arr = [string componentsSeparatedByString:[string substringWithRange:matchRange]];

    NSLog(@"Splitted String : %@", arr);
}
NeverHopeless
  • 11,077
  • 4
  • 35
  • 56
0

It may not be elegant but i would replace the isolated & for something else and then i would do the split.

Something like this (pseudo code, not IOS Syntax):

// s1 = "STRING1 && STRING2 & STRING3 AND STRING4";
aux=s1.replaceAll("([^&])&([^&])","$1 _SEPARATOR_ $2");
// in case of & at the beginning
aux=aux.replaceAll("^&([^&])"," _SEPARATOR_ $2");
// in case of & at the end
aux=aux.replaceAll("([^&])&$","$1 _SEPARATOR_ ");

// now aux="STRING1 && STRING2  _SEPARATOR_  STRING3 AND STRING4";
String[] params=aux.split(" _SEPARATOR_ ");
lalborno
  • 414
  • 3
  • 5