Как разобрать строку и найти двойники в Java - PullRequest
0 голосов
/ 03 апреля 2011

У меня есть следующий контент в файле, который мне нужно проанализировать.

((-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)) 

Пока что я отсканировал файл и построчно взял входные данные, сохранив их как строки, поэтому одна строка будет ((-2, -1), (4, 2)) ((-1,2, 0), (0, 0)).Мой вопрос, куда идти отсюда.Как мне извлечь парные числа из этой строки?Я пытался использовать скобки в качестве разделителя, а также меняя все скобки на запятые, а затем используя запятую в качестве разделителя, но оба эти способа дают мне ошибки.Любые идеи?

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)

Вся цель этого состоит в том, чтобы создавать очки из этих двойников.Например, ((0, 0), (10, -1)) создаст две точки, (0,0) и (10, -1).Я создал класс точек, и он принимает два двойных в конструкторе.Вот что я попробовал:

      String toParse = "((0, 0), (10, -1))";
    toParse.replaceAll("(", ",");
    toParse.replaceAll(")", ",");
    Scanner stringScanner = new Scanner(toParse);
    stringScanner.useDelimiter(",");
    while(stringScanner.hasNextDouble()){

ect

Ответы [ 3 ]

4 голосов
/ 03 апреля 2011

Вы получаете сообщение об ошибке, потому что ( и ) являются специальными символами регулярного выражения: поэтому, когда вы хотите заменить (или сопоставить) их, вам необходимо экранировать их обратной косой чертой:

toParse.replaceAll("\\(", ",");
...

Тем не менее, вы можете использовать подход Pattern / Matcher здесь:

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);
        }
    }
}

, который производит:

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

Что делает код: он ищет шаблон -?\d+(\.\d+)? и анализирует каждую строку, которая соответствует указанному шаблону, double.Сам шаблон означает:

-?         # an optional minus sign
\d+        # followed by one or more digits
(\.\d+)?   # followed by an optional decimal DOT with one or more digits
1 голос
/ 03 апреля 2011

Вот предложение для левого поля для вас.Найдите и замените скобки от ( и ) до [ и ], а затем просто используйте готовый анализатор JSON.

0 голосов
/ 03 апреля 2011

Следующий RegEx будет захватывать пару чисел, разделенных запятой и заключенных в скобки.Итак, он дал: ((4,2), он должен захватить: 4,2 И дал: ( -1.0,0) он бы захватил -1.0,0.С этого момента вы можете разделить строку на ,, обрезать начальные и конечные пробелы и проанализировать остаток как 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());
    }
} 
...