I have the following content in a file that I need to parse.
((-2, -1 ), ( 4, 2) ) ((-1.2, 0), (0, 0))
((0, 0), (10, -1))
((5, 3), (5, 4)) ((5, 1) , (5, 5))
((8, 3), (10, 3))
((8, 5), (11.5, 5))
So far, I have scanned through the file and taken the input line by line, saving them as strings, so one string would be ((-2, -1 ), ( 4, 2) ) ((-1.2, 0), (0, 0)). My question is where to go from here. How do I extract the doubles from this String. I have tried to use the parentheses as a delimiter, as well as changing all of the parentheses to commas, and then using a comma as a delimiter, but both of these ways give me errors. Any ideas?
Exception in thread "main" java.util.regex.PatternSyntaxException: Unclosed group near index 1 at java.util.regex.Pattern.error(Unknown Source) at
java.util.regex.Pattern.accept(Unknown Source) at
java.util.regex.Pattern.group0(Unknown Source) at
java.util.regex.Pattern.sequence(Unknown Source) at
java.util.regex.Pattern.expr(Unknown Source) at
java.util.regex.Pattern.compile(Unknown Source) at
java.util.regex.Pattern.<init>(Unknown Source) at
java.util.regex.Pattern.compile(Unknown Source) at
java.lang.String.replaceAll(Unknown Source)
The whole purpose of this is to create points from these doubles. For example, ((0, 0), (10, -1)) would create two points, (0,0) and (10, -1). I have created the point class and it takes in two doubles in the constructor. Here is what I tried:
String toParse = "((0, 0), (10, -1))";
toParse.replaceAll("(", ",");
toParse.replaceAll(")", ",");
Scanner stringScanner = new Scanner(toParse);
stringScanner.useDelimiter(",");
while(stringScanner.hasNextDouble()开发者_Go百科){
ect
The error message you get is because (
and )
are special regex characters: so whenever you want to replace (or match) them, you need to escape them with a backslash:
toParse.replaceAll("\\(", ",");
...
That said, you might want to use a Pattern/Matcher approach here:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
public static void main(String[] args) {
String source =
"((-2, -1 ), ( 4, 2) ) ((-1.2, 0), (0, 0)) \n" +
"((0, 0), (10, -1)) \n" +
"((5, 3), (5, 4)) ((5, 1) , (5, 5)) \n" +
"((8, 3), (10, 3)) \n" +
"((8, 5), (11.5, 5)) \n";
Matcher m = Pattern.compile("-?\\d+(\\.\\d+)?").matcher(source);
while(m.find()) {
double value = Double.parseDouble(m.group());
System.out.println("value=" + value);
}
}
}
which produces:
value=-2.0
value=-1.0
value=4.0
value=2.0
value=-1.2
value=0.0
value=0.0
value=0.0
value=0.0
value=0.0
value=10.0
value=-1.0
value=5.0
value=3.0
value=5.0
value=4.0
value=5.0
value=1.0
value=5.0
value=5.0
value=8.0
value=3.0
value=10.0
value=3.0
value=8.0
value=5.0
value=11.5
value=5.0
What the code does: it searches for the pattern -?\d+(\.\d+)?
and parses each string that matches said pattern to a double
. The pattern itself means:
-? # an optional minus sign
\d+ # followed by one or more digits
(\.\d+)? # followed by an optional decimal DOT with one or more digits
Here's a left-field suggestion for you. Search and replace the brackets from (
and )
to [
and ]
then use simply use an off-the-shelf JSON parser.
The following RegEx will capture the pair of numbers, separated by a comma and enclosed withing parantheses. So, it given: ((4,2),
it should capture: 4,2
And given: ( -1.0,0)
it would capture -1.0,0
. From that point on you can split the string by ,
trim the leading and trailing spaces and parse the remainder as a Double.
Pattern p = Pattern.compile("\(([^(]+,[^)]+)\)");
Matcher matcher = p.matcher("((-2, -1 ), ( 4, 2) ) ((-1.2, 0), (0, 0))");
while (matcher.find())
{
String str = matcher.group(); // this should in turn take the following values
// -2, -1
// 4, 2
// -1.2, 0
// 0, 0
String[] numbers = str.split(",");
if(numbers.length == 2)
{
// numbers[0] should be the first coordinate
// and numbers[1] should be the second
Double first = new Double(numbers[0].trim());
Double second = new Double(numbers[1].trim());
}
}
精彩评论