Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Regex pattern to match positive and negative number values in a String

I have pattern/matcher lines that transform input Strings like this:

1 3 Hi [2 1 4]

into an Array like this:

[0] => "1"
[1] => "3"
[2] => "Hi"
[3] => "2 1 4"

That's the code:

String input = sc.nextLine();

Pattern p = Pattern.compile("(?<=\\[)[^\\]]+|\\w+");
Matcher m = p.matcher(input);
List<String> cIn = new ArrayList<String>();
while(m.find()) cIn.add(m.group());

Now I realised that sometimes I could get some negative values, inputs like 4 2 -1 2. Since the input is a String, i can't really use any regular expression to get that negative value.

Below in the code, I use

Integer.parseInt(cIn.get(0)); 

to transform that string value into the Integer, that is actually what I need.

Could you figure a way that allows me to keep together the - char and the number char? Then I would just check if there's the - char to transform the number and multiply it by -1. (If there's a better way I'd be glad to hear).

As usual, excuse me for my English.

like image 417
afontcu Avatar asked Nov 17 '12 00:11

afontcu


3 Answers

You absolutely can use a regular expression to capture negative numbers, but it depends on what you're trying to weed out.

"(?<=\\[)[^\\]]+|[-\\w]+"

The simplest way is to simply add '-' to the group of recognized word characters. However, this will also result in weird formations like '9-9' being legal. Considering you already match tokens like '9_9', I'm not sure that's a problem for you. I'd probably just add another alternation to the end of this regex:

"(?<=\\[)[^\\]]+|\\w+|-?\\d+"

Which allows an optional '-' character followed by at least one digit. Or, a negative number. This is fairly robust - you're literally just defining an additional type of match (a very specific one), but every time you find a new case, you really shouldn't just keep adding '|...' to the end of your regex. It's about the least efficient way to do what you're doing. It seems, in your situation, that this isn't really a problem, but you should think about this as your use case expands.

like image 137
FrankieTheKneeMan Avatar answered Sep 24 '22 01:09

FrankieTheKneeMan


Here is the way: (?<=\\[)[^\\]]+|-?\\w+.

The -? regex means that you can have a - or not before the word (\\w+) but if you need only digits then use \\d+ and \\w+.

Here is the test i wrote:

@Test
public void regex() {

    String input = "-1 3 Hi [2 1 4]";

    Pattern p = Pattern.compile("(?<=\\[)[^\\]]+|-?\\w+");
    Matcher m = p.matcher(input);
    List<String> cIn = new ArrayList<String>();
    while (m.find())
        cIn.add(m.group());

    System.out.println(cIn);

}

It yields [-1, 3, Hi, 2 1 4] as you expect.

like image 45
ElderMael Avatar answered Sep 26 '22 01:09

ElderMael


You could use an optional - in your regex:

Pattern p = Pattern.compile("(?<=\\[)[^\\]]+|-?\\w+");
like image 41
Reimeus Avatar answered Sep 25 '22 01:09

Reimeus