Разбор файлов "/ etc / default" с использованием Java - PullRequest
1 голос
/ 19 апреля 2010

Я пытаюсь проанализировать файлы конфигурации, обычно находящиеся в /etc/default, используя java и регулярные выражения. Пока это код, который я повторяю для каждой строки в каждом файле:

// remove comments from the line
int hash = line.indexOf("#");
if (hash >= 0) {
    line = line.substring(0, hash);
}

// create the patterns
Pattern doubleQuotePattern = Pattern.compile("\\s*([a-zA-Z_][a-zA-Z_0-9]*)\\s*=\\s*\"(.*)\"\\s*");
Pattern singleQuotePattern = Pattern.compile("\\s*([a-zA-Z_][a-zA-Z_0-9]*)\\s*=\\s*\\'(.*)\\'\\s*");
Pattern noQuotePattern = Pattern.compile("\\s*([a-zA-Z_][a-zA-Z_0-9]*)\\s*=(.*)");

// try to match each of the patterns to the line
Matcher matcher = doubleQuotePattern.matcher(line);
if (matcher.matches()) {
    System.out.println(matcher.group(1) + " == " + matcher.group(2));
} else {
    matcher = singleQuotePattern.matcher(line);
    if (matcher.matches()) {
        System.out.println(matcher.group(1) + " == " + matcher.group(2));
    } else {
        matcher = noQuotePattern.matcher(line);
        if (matcher.matches()) {
            System.out.println(matcher.group(1) + " == " + matcher.group(2));
        }
    }
}

Это работает, как я и ожидал, но я уверен, что смогу уменьшить этот путь, используя лучшее регулярное выражение, но мне не повезло. Кто-нибудь знает, как лучше читать файлы такого типа?

Ответы [ 3 ]

2 голосов
/ 19 апреля 2010

Вы можете использовать antlr для генерации парсера. Обычно вы пишете грамматику для языка, с которым хотите работать (или используете одну из многих грамматик, уже написанных , и antlr сгенерирует для вас парсер.

1 голос
/ 19 апреля 2010

Вот один шаблон, который вы можете использовать, который эквивалентен трем, которые у вас есть выше:

Pattern etcPattern = Pattern.compile(
   "\\s*([a-zA-Z_]\\w*)\\s*=\\s*"+
   "(\"|'|.{0,0})(.*?)\\2"+  //QUOTE MATCHING
   "\\s*");

Существует три различия между этим и вашим: сначала я заменил выражение [a-zA-Z0-9_] на его предопределенный класс символов \ w (символ слова). Вторая часть (QUOTE MATCHING) - это шаблон, который будет сопоставлять и отбрасывать внешние сбалансированные кавычки, но также разрешать несбалансированные кавычки, как это делали ваши три шаблона.

Он начинается с использования шаблона (\ "| '|. {0,0}). Это

  1. Двойная кавычка
  2. Одиночная цитата
  3. Что-нибудь ноль раз

Затем ваш шаблон. *, За которым следует обратная ссылка \ 2. Обратная ссылка говорит, чтобы соответствовать тому, что было сопоставлено с шаблоном 2 (образец цитаты). Вот где третий случай выше важен. Если значение не начинается с одинарной или двойной кавычки, оно должно быть в состоянии игнорировать его. Таким образом, он начинается с попытки сопоставить одну из цитат. Если это невозможно, то он будет соответствовать пустой строке, что, в свою очередь, позволяет обратным ссылкам соответствовать пустой строке.

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

Так что вы должны иметь возможность запустить это как:

Matcher matcher = etcPattern.matcher(line);
if (matcher.matches()) {
    System.out.println(matcher.group(1) + " == " + matcher.group(3));
}

эквивалентно вашему примеру выше (обратите внимание, что значение теперь находится в группе совпадений 3 вместо двух. Как я уже сказал, это соответствует тому, что сделали ваши шаблоны, в частности, это позволит использовать несбалансированные кавычки и разрешить любые внутренние кавычки для значения.

1 голос
/ 19 апреля 2010

Во многих случаях вы можете использовать java.util.Properties для обработки файлов конфигурации оболочки.

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

Вещи, которые не очень хорошо обрабатываются, это строки в кавычках.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...