Требуется регулярное выражение для анализа многострочных переменных среды - PullRequest
0 голосов
/ 01 ноября 2018

Я хочу проанализировать файл, представляющий собой список переменных среды, аналогичных приведенному в этом примере:

TPS_LIB_DIR = "$DEF_VERSION_DIR\lib\ver215";

TPS_PH_DIR = "$DEF_VERSION_DIR";

TPS_SCHEMA_DIR = "~TPS_DIR\Supersedes\code;" +
                "~TPR_DIR\..\Supersedes\code;" +
                "~TPN_DIR\..\..\Supersedes\code;" +
                "$TPS_VERSION_DIR";

TPS_LIB_DIR = "C:\prog\lib";

BASE_DIR     = "C:\prog\base";

SPARS_DIR    = "C:\prog\spars";

SIGNALFILE_DIR = "E:\SIGNAL_FILES";
SIGNALFILE2_DIR = "E:\SIGNAL_FILES2";
SIGNALFILE3_DIR = "E:\SIGNAL_FILES2";

Я придумал это регулярное выражение, которое точно соответствует однострочным определениям, но оно не будет соответствовать многострочным определениям.

(\w+)\s*=\s*(.*);[\r\n]+

Кто-нибудь знает регулярное выражение, которое будет анализировать все строки в этом файле, где имя переменной среды находится в группе 1, а значение (справа от =) находится в группе 2? Еще лучше было бы, если бы несколько путей были в отдельных группах, но я могу обработать эту часть вручную.

UPDATE:

Вот что я в итоге реализовал. Первый шаблон «Шаблон p» соответствует отдельным блокам переменных среды. Второй шаблон «Шаблон valpattern» анализирует одно или несколько значений для каждой переменной среды. Надеюсь, кто-нибудь найдет это полезным.

private static void parse(File filename) {
    Pattern p = Pattern.compile("(\\w+)\\s*=\\s*([\\s\\S]+?\";)");
    Pattern valpattern = Pattern.compile("\\s*\"(.+)\"\\s*");
    try {
        String str = readFile(filename, StandardCharsets.UTF_8);
        Matcher matcher = p.matcher(str);
        while(matcher.find()) {
            String key = matcher.group(1);
            Matcher valmatcher = valpattern.matcher(matcher.group(2));
            System.out.println(key);
            while(valmatcher.find()) {                  
                System.out.println("\t" + valmatcher.group(1).replaceAll(System.getProperty("line.separator"), ""));
            }
        }
    } catch (IOException e) {
        System.out.println("Error: ProcessENV.parse -- problem parsing file: " + filename + System.lineSeparator());
        e.printStackTrace();
    }
}

static String readFile(File file, Charset encoding) throws IOException {
    byte[] encoded = Files.readAllBytes(file.toPath());
    return new String(encoded, encoding);
}

Ответы [ 2 ]

0 голосов
/ 02 ноября 2018

Вы можете использовать следующее регулярное выражение:

(\w+)\s*=\s*([\s\S]+?)";

Начнется с сопоставления группы 1 из Word символа, нуля или более White Spaces, equal sign, нуля или более White Space, затем группы 2 или более any символов (non greedy) и, наконец, последний двойной quote и semi colon.

Это будет соответствовать всем строкам.

0 голосов
/ 01 ноября 2018

Проще разделить на '=' и '";'.

[ c.strip().split(' = ') for c in s.split('";') ] 

Или с двойным пониманием, чтобы получить индивидуальные пути:

[ [p[0].strip(), * [x.strip() for x in p.strip().split('=')] for c in s.split('";') for p in c.split(" = ")] 

Разделение можно выполнить с помощью re, добавив \ s * для удаления завершающих пробелов:

 re.split(r'\s*=\s*|";\s*', text, flags=re.MULTILINE):

четные элементы r [:: 2] будут переменными, нечетные [1 :: 2] значения затем избавьтесь от лишних пробелов в значениях

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