исключение stackoverflow при использовании совпадения строк в Java - PullRequest
1 голос
/ 02 апреля 2011

Для небольшого университетского проекта, который я делаю, мне нужно извлечь примеры кода из HTML, заданного в виде строки.Точнее, мне нужно получить из этой строки HTML, все между <code> и .

Я пишу на Java и использую для этого String.match.

Мой код:

public static ArrayList<String> extractByHTMLtagDelimiters(String source, String startDelimiter, String endDelimiter){
ArrayList<String> results = new ArrayList<String>();
if (source.matches("([\t\n\r]|.)*" + startDelimiter + "([\t\n\r]|.)*" + endDelimiter)){
    //source has some code samples in it
    //get array entries of the form: {Some code}</startDelimiter>{something else}
    String[] splittedSource = source.split(startDelimiter);
        for (String sourceMatch : splittedSource){
        if (sourceMatch.matches("([\t\n\r]|.)*" + endDelimiter + "([\t\n\r]|.)*")){
            //current string has code sample in it (with some body leftovers)
            //the code sample located before the endDelimiter - extract it
            String codeSample = (sourceMatch.split(endDelimiter))[0];
            //add the code samples to results
            results.add(codeSample);
        }
        }
}
return results;

iv'e пытался извлечь эти образцы из некоторыхhtml ~ 1300 символов и получил довольно массовое исключение: (оно продолжается и продолжается в течение нескольких десятков строк)

Exception in thread "main" java.lang.StackOverflowError
at java.util.regex.Pattern$Branch.match(Unknown Source)
at java.util.regex.Pattern$GroupHead.match(Unknown Source)
at java.util.regex.Pattern$Loop.match(Unknown Source)
at java.util.regex.Pattern$GroupTail.match(Unknown Source)
at java.util.regex.Pattern$BranchConn.match(Unknown Source)
at java.util.regex.Pattern$CharProperty.match(Unknown Source)
at java.util.regex.Pattern$Branch.match(Unknown Source)
at java.util.regex.Pattern$GroupHead.match(Unknown Source)
at java.util.regex.Pattern$Loop.match(Unknown Source)
at java.util.regex.Pattern$GroupTail.match(Unknown Source)
at java.util.regex.Pattern$BranchConn.match(Unknown Source)
at java.util.regex.Pattern$CharProperty.match(Unknown Source)
at java.util.regex.Pattern$Branch.match(Unknown Source)
at java.util.regex.Pattern$GroupHead.match(Unknown Source)
at java.util.regex.Pattern$Loop.match(Unknown Source)
at java.util.regex.Pattern$GroupTail.match(Unknown Source)
at java.util.regex.Pattern$BranchConn.match(Unknown Source)
at java.util.regex.Pattern$CharProperty.match(Unknown Source)
at java.util.regex.Pattern$Branch.match(Unknown Source)
at java.util.regex.Pattern$GroupHead.match(Unknown Source)
at java.util.regex.Pattern$Loop.match(Unknown Source)

Я нашел следующий отчет об ошибке: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5050507

Что я могу сделать, чтобы все еще использовать string.match?если нет, то можете ли вы порекомендовать какой-то другой способ сделать это без самостоятельной реализации html-разбора?

Большое спасибо, Даб.

Ответы [ 2 ]

3 голосов
/ 02 апреля 2011

Вы можете просто вручную просмотреть строку ввода с помощью метода indexOf () в String, чтобы найти начальный и конечный разделители и извлечь биты между собой.

public static void main(String[] args) {
    String source = "<html>blah<code>this is awesome</code>more junk</html>";

    String startDelim = "<code>";
    String endDelim = "</code>";
    int start = source.indexOf(startDelim);
    int end = source.indexOf(endDelim);

    String code = source.substring(start + startDelim.length(), end);
    System.out.println(code);
}

Если вам нужно найти более одного, затем просто используйте indexOf, снова начиная с точки, которую вы закончили:

int nextStart = source.indexOf(startDelim, end + endDelim.length())
1 голос
/ 02 апреля 2011

Просто замените ваш шаблон регулярного выражения на "(?s).*"

Это соответствует чему угодно, включая новые строки, как вы и планировали.

...