Extracting complex numbers from a string JAVA

Viewed 77

I would want to extract the numbers from a complex expression given as a string. Example:

Input: '2+3*i + 1-4*i + -2*i'.
Output: 2 , 3 , 1, -4 , -2.

I tried to parse them using split("-|\\+|\\*") but i lose the sign for the negative numbers, any suggestions ?

3 Answers

I would like to use Pattern and Matcher in your case like this:

String str = "2+3i + 1-4i + -2i";
Pattern pattern = Pattern.compile("[-+]?\\d+");
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
    System.out.println(matcher.group());
}

Output

2
+3
1
-4
-2

Add look arounds to handle minus then a digit:

.split("(\\*i)? *((?<=\\d)(?=-)|-(?!\\d)|\\+|$) *")

See live demo, showing that

System.out.println(Arrays.toString(
"2+3*i + 1-4*i + -2*i"
.split("(\\*i)? *((?<=\\d)(?=-)|-(?!\\d)|\\+|$) *")
));

Outputs the desired result (also tested with minus signs between terms):

[2, 3, 1, -4, -2]

Look arounds assert, but don’t consume, input, which is what you need here.

I added more to the regex to also discard the stuff around the numbers.

An addition to @YCF_L's answer if you want to have the match results in an array

import java.util.Arrays;
import java.util.regex.MatchResult;
import java.util.regex.Pattern;

public class Test {

    public static void main(String[] args) {
        String str = "2+3*i + 1-4*i + -2*i";
        String[] nums = Pattern.compile("(-?)\\d+")
                               .matcher(str)
                               .results()
                               .map(MatchResult::group)
                               .toArray(String[]::new);
        
        System.out.println(Arrays.toString(nums));
    }
}

here, however, it is no longer recognisable which numbers were assigned to the real and which to the imaginary part of a complex number

If you want to have the numbers as int instead of strings:

int[] nums = Pattern.compile("(-?)\\d+")
                    .matcher(str)
                    .results()
                    .map(MatchResult::group)
                    .mapToInt(Integer::parseInt)
                    .toArray();
Related