Код: Выделить всё
public static void parse(String input)
{
String KV_REGEX = "((?:\"[^\"^ ]*\"|[^=,^ ])*) *= *((?:\"[^\"]*\"|[^=,^\\)^ ])*)";
Pattern KV_PATTERN = Pattern.compile(KV_REGEX);
Matcher matcher = KV_PATTERN.matcher(input);
System.out.println("\nMatcher groups discovered:");
while (matcher.find())
{
System.out.println(matcher.group(1) + ", " + matcher.group(2));
}
}
< /code>
Некоторые фиктивные примеры вывода: < /p>
String input1 = "2012-08-09 09:10:25,521 INFO com.a.package.SomeClass - Everything working fine {name=CentOS, family=Linux, category=OS, version=2.6.x}";
String input2 = "2012-08-09 blah blah 09:12:38,462 Log for the main thread, PID=5872, version=\"7.1.8.x\", build=1234567, other=done";
< /code>
Callse parse (input1) < /code> создает: < /p>
{name, CentOS
family, Linux
category, OS
version, 2.6.x}
< /code>
Callse parse (input2) < /code> создает: < /p>
PID, 5872
version, "7.1.8.x"
build, 1234567
other, done
< /code>
Это нормально (даже с небольшой обработкой строки, необходимой для первого случая). Однако при попытке проанализировать очень длинную (более 1000 символов) строка ClassPath, вышеупомянутый переполнение класса происходит, за следующим исключением (Start): < /p>
Exception in thread "main" java.lang.StackOverflowError
at java.util.regex.Pattern$BitClass.isSatisfiedBy(Pattern.java:2927)
at java.util.regex.Pattern$8.isSatisfiedBy(Pattern.java:4783)
at java.util.regex.Pattern$8.isSatisfiedBy(Pattern.java:4783)
at java.util.regex.Pattern$8.isSatisfiedBy(Pattern.java:4783)
at java.util.regex.Pattern$8.isSatisfiedBy(Pattern.java:4783)
at java.util.regex.Pattern$CharProperty.match(Pattern.java:3345)
...
< /code>
Строка слишком длинная, чтобы поместить здесь, но она имеет следующую, легко воспроизводимую и повторяющуюся структуру: < /p>
java.class.path=/opt/files/any:/opt/files/any:/opt/files/any:/opt/files/any
Есть ли общий способ, которым приведенный выше KV_Regex может быть изменен, так что проблема не возникает, и я не достигнут, что ярко -ясные, что я иной, явной? В отличие от взломов, которые (например) проверяют максимальную длину строки перед анализом.public void safeParse(String input)
{
try
{
parse(input);
}
catch (StackOverflowError e) // Or even Throwable!
{
parse(input.substring(0, MAX_LENGTH));
}
}
< /code>
Как ни странно, он работает в нескольких пробегах, которые я попробовал, но это не достаточно со вкусом, чтобы рекомендовать.
Подробнее здесь: https://stackoverflow.com/questions/118 ... k-overflow