Есть ли простой способ разбора этого текста на карту - PullRequest
7 голосов
/ 15 января 2012

Я получаю ответ от службы, как показано ниже. Как разобрать это в Map? Сначала я подумал о разбиении в пробелах, но он не работает, так как значение может содержать пробелы, например посмотрите на значение SA введите ниже ответ.

Один из вариантов, о котором я подумал, это разделить пробел при условии предыдущий символ - двойная кавычка. Не уверен, как написать регулярное выражение для этого.

TX = "0000000000108000001830001" FI = "" OS = "8" CI = "QU01SF1S2032" AW = "SSS" SA = "1525 Наветренный зал"

Ответы [ 3 ]

4 голосов
/ 15 января 2012

Разбор в кавычках.Вы даже можете использовать регулярное выражение для поиска каждой пары ключ / значение, предполагая, что каждое значение находится в кавычках.Мой единственный вопрос: каковы правила, если значение содержит вложенные кавычки?(Они сбежали, используя '\' или что-то подобное? Независимо от того, что в настоящее время не учитывается в приведенном ниже ...)

Например:

(\w+)="([^"]*)"

Это даже даст вам группы# 1 и # 2, которые можно использовать для предоставления ключа и значения, соответственно.

Запустите это в цикле, используя метод Java Matcher.find(), пока не найдете все пары.

Пример кода:

String input = "TX=\"0000000000108000001830001\" FI=\"\" OS=\"8\" CI=\"QU01SF1S2032\" AW=\"SSS\" SA=\"1525 Windward Concourse\"";

Pattern p = Pattern.compile("\\s*(\\w+)=\"([^\"]*)\"\\s*");

Matcher m = p.matcher(input);
while(m.find()){
    System.out.println(m.group(1));
    System.out.println(m.group(2));
}

Выход:

TX
0000000000108000001830001
FI

OS
8
CI
QU01SF1S2032
AW
SSS
SA
1525 Windward Concourse
3 голосов
/ 15 января 2012

По внешнему виду текста кажется, что это может быть XML.Это так, или этот текст является необработанным ответом службы?Если это XML, вы можете легко его проанализировать с помощью Groovy XmlSlurper:

def input = '<root TX="0000000000108000001830001" FI="" OS="8" CI="QU01SF1S2032" AW="SSS" SA="1525 Windward Concourse"></root>'
def xml = new XmlSlurper().parseText(input)

def map = xml.attributes()

Переменная map будет [CI:QU01SF1S2032, AW:SSS, TX:0000000000108000001830001, OS:8, FI:, SA:1525 Windward Concourse]

Если это не XML, вы можете следовать Ziesemer ответ и использовать регулярное выражение.Отличная версия его ответа, которая генерирует Map, будет выглядеть так:

def input = 'TX="0000000000108000001830001" FI="" OS="8" CI="QU01SF1S2032" AW="SSS" SA="1525 Windward Concourse"'
def match = input =~ /(\w+)="([^"]*)"/

def map = [:]
match.each {
    map[it[1]] = it[2]
}

Результат map будет таким же, как и раньше.

2 голосов
/ 15 января 2012

StreamTokenizer работает быстро, хотя я не использовал функцию quoteChar().Примеры можно найти здесь , здесь и здесь .

Консоль:

TX=0000000000108000001830001
FI=
OS=8
CI=QU01SF1S2032
AW=SSS
SA=1525 Windward Concourse
Count: 6
0.623 ms

Код:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StreamTokenizer;
import java.io.StringReader;

/** @see https://stackoverflow.com/questions/8867325 */
public class TokenizerTest {

    private static final String s = ""
        + "TX=\"0000000000108000001830001\" FI=\"\" OS=\"8\" "
        + "CI=\"QU01SF1S2032\" AW=\"SSS\" SA=\"1525 Windward Concourse\"";
    private static final char equal = '=';
    private static final char quote = '"';
    private static StreamTokenizer tokens = new StreamTokenizer(
        new BufferedReader(new StringReader(s)));

    public static void main(String[] args) {
        long start = System.nanoTime();
        tokenize();
        long stop = System.nanoTime();
        System.out.println((stop - start) / 1000000d + " ms");
    }

    private static void tokenize() {
        tokens.ordinaryChar(equal);
        tokens.quoteChar(quote);
        try {
            int count = 0;
            int token = tokens.nextToken();
            while (token != StreamTokenizer.TT_EOF) {
                if (token == StreamTokenizer.TT_WORD) {
                    System.out.print(tokens.sval);
                    count++;
                }
                if (token == equal) {
                    System.out.print(equal);
                }
                if (token == quote) {
                    System.out.println(tokens.sval);
                }
                token = tokens.nextToken();
            }
            System.out.println("Count: " + count);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...