1

I have to validate and match numbers in a string. Acceptable formats:

11, 
-11, 
+11, 
(11), 
(+11), 
(-11).

Half parenthesis are not acceptable.

I have created a regex which will match

11, 
-11, 
+11: 

[\-\+]?\d++ 

This works well. I have created a pattern to apply to the parenthesis version too. This String is a base input for the string format method: ^(\(%1$s\))|(%1$s)$ where the simple parenthesis are for the the group capture and the escaped are for the match. The result is:

^(\([\-\+]?\d++\))|([\-\+]?\d++)$  

This match for the above strings also match the (+11. Which is not acceptable. Also if the filter with parenthesis is the second condition than it match to the +11).

Any idea how to improve this?

UPDATE: I can't delete this post, but it's wrong. I made that mistake to use the find method instead of match. My regex is good and working.

Péter
  • 2,091
  • 3
  • 21
  • 30

3 Answers3

2

Not sure if I understand your issue, but here's a working Pattern with your input - assuming all tokens are in the same String:

String input = "11, -11, +11, (11), (+11), (-11).";
//                           > escaped parenthesis
//                           |  > group 1
//                           |  | > sign
//                           |  | |   > digits
//                           |  | |   |  > EOF group 1
//                           |  | |   |  | > escaped parenthesis
//                           |  | |   |  | |  > alternate
//                           |  | |   |  | |  |> group 2
//                           |  | |   |  | |  || > sign
//                           |  | |   |  | |  || |   > digits
//                           |  | |   |  | |  || |   |  > EOF group 2
//                           |  | |   |  | |  || |   |  |
Pattern p = Pattern.compile("\\(([+-]?\\d+)\\)|([+-]?\\d+)");
Matcher m = p.matcher(input);
while (m.find()) {
    System.out.println(m.group());
    if (m.group(1) != null) {
        System.out.printf("\t%s\n", m.group(1));
    }
    else if (m.group(2) != null) {
        System.out.printf("\t%s\n", m.group(2));
    }
}

Output

11
    11
-11
    -11
+11
    +11
(11)
    11
(+11)
    +11
(-11)
    -11
Mena
  • 45,491
  • 11
  • 81
  • 98
0

it might not be the most efficient way but you can match any number that has parantheses before and after OR that doesn't have parantheses before and after:

(?<=\()[\+\-]?\d++(?=\))|(?<![\(\+\-\d])[\+\-]?\d++(?!\))

(?<=\() is a positive look behind and (?=\)) positive look ahead, it will only match if both are true.

same thing with (?<![\(\+\-\d]) -- edit -- negative look behind and (?!\)) negative look ahead, will only match if both are false.

The match however doesn't include the parantheses, only the numbers with the sign, if you want to match parantheses as well just remove the positive look ahead\behind

\([\+\-]?\d++\)|(?<![\(\+\-\d])[\+\-]?\d++(?!\)) --edit--

Test it yourself before using it, I can't guarantee that I'm correct here, I'm not the most experienced guy around.

Also for more info about regexp you can have a look at http://www.regular-expressions.info/ it's a wonderful resource.

edit: Think it will match also something like this "(-535" as 535 doesn't have ( before it and ), will only match the number but not the sign, so had to add digits and sign to the negative lookbehind, still could be more bugs in there

-1

I do not really understand why did you try to use 2 patterns: with and without parenthesis. I'd suggest you the following: \(?([+-]?\\d+)\)?. This pattern captures any sequence of digits optionally prepended by + or - whether wrapped with parenthesis or not.

AlexR
  • 109,181
  • 14
  • 116
  • 194