/ / Проблеми с Regex за съдържание, прекратено с нов ред - java, regex

Проблеми с Regex за съдържание, прекратено с нов ред - java, regex

Имам следния String:

String script = "%NAME%n"
+ "adwaita-icon-themen"
+ "n"
+ "%VERSION%n"
+ "3.20-1n"
+ "n"
+ "%DESC%n"
+ "Adwaita icon themen"
+ "n"
+ "%URL%n"
+ "http://www.gnome.orgn"
+ "n"
+ "%ARCH%n"
+ "anyn"
+ "n"
+ "%BUILDDATE%n"
+ "1458859575n"
+ "n"
+ "%INSTALLDATE%n"
+ "1461498688n"
+ "n"
+ "%PACKAGER%n"
+ "Jan de Groot <jgc@archlinux.org>n"
+ "n"
+ "%SIZE%n"
+ "24542208n"
+ "n"
+ "%REASON%n"
+ "1n"
+ "n"
+ "%GROUPS%n"
+ "gnomen"
+ "n"
+ "%LICENSE%n"
+ "GPLn"
+ "n"
+ "%VALIDATION%n"
+ "pgpn"
+ "n"
+ "%DEPENDS%n"
+ "hicolor-icon-themen"
+ "gtk-update-icon-cachen"
+ "librsvgn";

Това са суровите данни от файла:

%NAME%
adwaita-icon-theme

%VERSION%
3.20-1

%DESC%
Adwaita icon theme

%URL%
http://www.gnome.org

%ARCH%
any

%BUILDDATE%
1458859575

%INSTALLDATE%
1461498688

%PACKAGER%
Jan de Groot <jgc@archlinux.org>

%SIZE%
24542208

%REASON%
1

%GROUPS%
gnome

%LICENSE%
GPL

%VALIDATION%
pgp

%DEPENDS%
hicolor-icon-theme
gtk-update-icon-cache
librsvg

Трябва да заснема съдържанието с % и всичко под него. Имам проблеми с прекратяването. Опитах това:

\%(.*)\%\n((?s:.*))

И правилно улавя първата група, но след това улавя следващата също като част от първия израз. Така че с това:

Pattern p = Pattern.compile("\%(.*)\%\n((?s:.*))");
Matcher m = p.matcher(script);

while (m.find()) {
System.out.println(m.group(1));
System.out.println(m.group(2));
}

Получавам това:

run:
NAME
adwaita-icon-theme

%VERSION%
3.20-1

%DESC%
Adwaita icon theme

%URL%
http://www.gnome.org

%ARCH%
any

%BUILDDATE%
1458859575

%INSTALLDATE%
1461498688

%PACKAGER%
Jan de Groot <jgc@archlinux.org>

%SIZE%
24542208

%REASON%
1

%GROUPS%
gnome

%LICENSE%
GPL

%VALIDATION%
pgp

%DEPENDS%
hicolor-icon-theme
gtk-update-icon-cache
librsvg

BUILD SUCCESSFUL (total time: 0 seconds)

Първият получава правилно улавяне, но останалите се улавят като група 2 на първия израз. Знам това, защото в изхода не трябва да има % знаци.

Как да заснемете съдържанието под % { ... } % маркери като група, а съдържанието вътре в маркерите като друго.

Това ми трябва за строго откриване. Използване на Java 8 на Linux.

Отговори:

0 за отговор № 1

Използвате DOTALL ?s знаме във вашата втора група, така че . ще съвпада с всичко, включително емисии на линии, а втората група ще съдържа останалата част от файла.

Вашата втора група трябва някъде да съдържа няколко реда (например за %DEPENDS% блок), но никога не трябва да съвпада с следващия %, Така че вместо да използвате a DOTALLизд ., Бих предложил да използвате отрицателния клас [^%] които трябва да съответстват на емисиите на линиите, без да е необходимо DOTALL флаг, но няма да съответства на следващия %.

Регексът ви ще стане след това \%(.*)\%\n([^%]*).
Забележка: В крайна сметка премахнах чифт скоби, защото не видях нужда от това.
Забележка 2: Вашият регекс може да е малко по-ефективен като \%([^%]*)\%\n([^%]*).

Вижте го в действие тук.