Java Извлечение текста между тегами и атрибутами - PullRequest
0 голосов
/ 06 мая 2018

Я пытаюсь извлечь текст между определенными тегами и атрибутами. На данный момент я попытался извлечь для тегов. Я читаю файл «.gexf», в котором есть данные XML. Затем я сохраняю эти данные в виде строки. Затем я пытаюсь извлечь текст между тегами "узлов". Вот мой код:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    private static String filePath = "src/babel.gexf";

    public String readFile(String filePath) throws IOException {
        BufferedReader br = new BufferedReader(new FileReader(filePath));
        try {
            StringBuilder sb = new StringBuilder();
            String line = br.readLine();
            while (line != null) {
                sb.append(line);
                sb.append("\n");
                line = br.readLine();
            }
            return sb.toString();
        } finally {
            br.close();
        }
    }

    public void getNodesContent(String content) throws IOException {
        final Pattern pattern = Pattern.compile("<nodes>(\\w+)</nodes>", Pattern.MULTILINE);
        final Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            System.out.println(matcher.group(1));
        }
    }

    public static void main(String [] args) throws IOException {
        Main m = new Main();
        String result = m.readFile(filePath);
        m.getNodesContent(result);
    }
}

В приведенном выше коде я не получаю никакого результата. Когда я пробую это с примером строки, такой как «Моя строка», я получаю результат. Ссылка на файл gexf (поскольку он слишком длинный, мне пришлось его загрузить): https://files.fm/u/qag5ykrx

Ответы [ 2 ]

0 голосов
/ 06 мая 2018

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

Полагаю, вы можете попробовать этот маленький метод. В основе этого лежит регулярное выражение (RegEx) вместе с Pattern / Matcher для извлечения нужной подстроки между тегами.

Важно читать документы по методу:

<code>/**
 * This method will retrieve a string contained between string tags. You
 * specify what the starting and ending tags are within the startTag and
 * endTag parameters. It is you who determines what the start and end tags
 * are to be which can be any strings.<br><br>
 *
 * @param inputString (String) Any string to process.<br>
 *
 * @param startTag (String) The Start Tag String or String. Data content retrieved
 * will be directly after this tag.<br><br>
 *
 * The supplied Start Tag criteria can contain a single special wildcard tag
 * (~*~) providing you also place something like the closing chevron (>)
 * for an HTML tag after the wildcard tag, for example:<pre>
 *
 * If we have a string which looks like this:
 *      {@code
 *      "<p style=\"padding-left:40px;\">Hello</p>"
 *      }
 *      (Note: to pass double quote marks in a string they must be excaped)
 *
 * and we want to use this method to extract the word "Hello" from between the
 * two HTML tags then your Start Tag can be supplied as "&lt;p~*~&gt;" and of course
 * your End Tag can be "&lt;/p&gt;". The "&lt;p~*~&gt;" would be the same as supplying
 * "&lt;p style=\"padding-left:40px;\"&gt;". Anything between the characters &lt;p and
 * the supplied close chevron (&gt;) is taken into consideration. This allows for
 * contents extraction regardless of what HTML attributes are attached to the
 * tag. The use of a wildcard tag (~*~) is also allowed in a supplied End
 * Tag.

* * Подстановочный знак используется в качестве специального тега, так что строки, которые на самом деле * содержат звездочки (*) могут быть обработаны как обычные звездочки.
* * @param endTag (String) Конечный тег или строка. Поиск данных будет * конец до того, как этот тег будет достигнут.
* * Предоставленные критерии конечного тега могут содержать один специальный шаблонный тег * (~ * ~) при условии, что вы также поместите что-то вроде закрывающего шеврона (& gt;) * для тега HTML после тега подстановки, например:
 *
 * If we have a string which looks like this:
 *      {@code
 *      "<p style=\"padding-left:40px;\">Hello</p>"
 *      }
 *      (Note: to pass double quote marks in a string they must be excaped)
 *
 * and we want to use this method to extract the word "Hello" from between the
 * two HTML tags then your Start Tag can be supplied as "&lt;p style=\"padding-left:40px;\"&gt;"
 * and your End Tag can be "&lt;/~*~&gt;". The "&lt;/~*~&gt;" would be the same as supplying
 * "&lt;/p&gt;". Anything between the characters &lt;/ and the supplied close chevron (&gt;)
 * is taken into consideration. This allows for contents extraction regardless of what the
 * HTML tag might be. The use of a wildcard tag (~*~) is also allowed in a supplied Start Tag.

* * Подстановочный знак используется в качестве специального тега, так что строки, которые на самом деле * содержат звездочки (*) могут быть обработаны как обычные звездочки.
* * @param trimFoundData (Необязательно - Boolean - По умолчанию установлено значение true) По умолчанию * все извлеченные данные обрезаются от начальных и конечных пробелов. Если * вы не хотите этого, тогда укажите false для этого необязательного параметра. * * @return (1D String Array) Если существует более одной пары Начального и Конечного * Теги, содержащиеся в предоставленной входной строке, затем помещают каждый набор * в массив отдельно.
* * @throws IllegalArgumentException, если любой предоставленный метод String аргумент * нулевой (""). * / public static String [] getBetweenTags (String inputString, String startTag, String endTag, логическое значение ... trimFoundData) { if (inputString == null || inputString.equals ("") || startTag == null || startTag.equals ("") || endTag == ноль || endTag.equals ("")) { бросить новый IllegalArgumentException ("\ ngetBetweenTags () Ошибка метода! -" + "Предоставленный аргумент метода содержит Null (\" \ ")! \ N" + «Предоставленные аргументы метода: \ n» + "========================== \ n" + "inputString = \" "+ inputString +" \ "\ n" + "startTag = \" "+ startTag +" \ "\ n" + "endTag = \" "+ endTag +" \ "\ n"); } List list = new ArrayList <> (); логическое trimFound = true; if (trimFoundData.length> 0) { trimFound = trimFoundData [0]; } Matcher Matcher; if (startTag.contains ("~ * ~") || endTag.contains ("~ * ~")) { startTag = startTag.replace ("~ * ~", ". *?"); endTag = endTag.replace ("~ * ~", ". *?"); Pattern pattern = Pattern.compile ("(? Iu)" + startTag + "(. *?)" + EndTag); matcher = pattern.matcher (inputString); } еще { String regexString = Pattern.quote (startTag) + "(? S) (. *?)" + Pattern.quote (endTag); Pattern pattern = Pattern.compile ("(? Iu)" + regexString); matcher = pattern.matcher (inputString); } while (matcher.find ()) { Соответствие строки = matcher.group (1); if (trimFound) { match = match.trim (); } list.add (совпадение); } вернуть list.toArray (new String [list.size ()]); }
0 голосов
/ 06 мая 2018

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

String s = "<a>test</a><b>list</b><a>class</a>";
int start = 0,  end = 0;
for(int i = 0; i < s.toCharArray().length-1; i++){
    if(s.toCharArray()[i] == '<' && s.toCharArray()[i+1] == 'a' &&     s.toCharArray()[i+2] == '>'){
        start = i+3;
        for(int j = start+3; j < s.toCharArray().length-1; j++){
            if(s.toCharArray()[j] == '<' && s.toCharArray()[j+1] == '/' && s.toCharArray()[j+2] == 'a' && s.toCharArray()[j+3] == '>'){
                end = j;
                System.out.println(s.substring(start, end));
                break;
            }
        }
    }
}

Приведенный выше код будет искать в строке s тег, а затем начинать с того места, где он его нашел, и продолжаться, пока не найдет закрывающий тег. затем он использует эти две позиции для создания подстроки строки, которая является текстом между двумя тегами. Вы можете составить столько поисков по тегам, сколько захотите. Вот пример поиска по 2 тегам:

String s = "<a>test</a><b>list</b><a>class</a>";
int start = 0,  end = 0;
for(int i = 0; i < s.toCharArray().length-1; i++){
    if((s.toCharArray()[i] == '<' && s.toCharArray()[i+1] == 'a' && s.toCharArray()[i+2] == '>') ||
            (s.toCharArray()[i] == '<' && s.toCharArray()[i+1] == 'b' && s.toCharArray()[i+2] == '>')){
        start = i+3;
        for(int j = start+3; j < s.toCharArray().length-1; j++){
            if((s.toCharArray()[j] == '<' && s.toCharArray()[j+1] == '/' && s.toCharArray()[j+2] == 'a' && s.toCharArray()[j+3] == '>') || 
                    (s.toCharArray()[j] == '<' && s.toCharArray()[j+1] == '/' && s.toCharArray()[j+2] == 'b' && s.toCharArray()[j+3] == '>')){
                end = j;
                System.out.println(s.substring(start, end));
                break;
            }
        }
    }
}

Единственное отличие состоит в том, что я добавил предложения к операторам if, чтобы также получить текст между тегами b. Эта система чрезвычайно универсальна, и я думаю, что вы будете финансировать изобилие ее использования.

...