Тестил со строкой, что указана как пример в условии задачи, а также с другой строкой, которая была подсказана валидатором при совершении другой ошибки.
В обоих случаях вывод на экран корректный (если есть вложенные теги, то сначала весь тег выводится, а только затем вложенный), но валидатор все равно бухтит.
package com.javarush.task.task19.task1918;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/*
Знакомство с тегами
*/
public class Solution {
public static void main(String[] args) {
try(BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
BufferedReader fileReader = new BufferedReader(new FileReader(reader.readLine()))) {
List<Integer> startTagPositions = new ArrayList<>();
List<Integer> endTagPositions = new ArrayList<>();
String fileText = "";
while(fileReader.ready()) {
fileText = fileText + fileReader.readLine();
}
fileText = fileText.replaceAll("\\n\\r", "");
int startPos = 0, endPos = 0;
while (startPos >=0) {
startPos = fileText.indexOf("<" + args[0], startPos);
if (startPos >= 0) startTagPositions.add(startPos++);
endPos = fileText.indexOf("</" + args[0] + ">", endPos) + 6;
if (endPos >= 6) endTagPositions.add(endPos);
}
while (!startTagPositions.isEmpty()) {
int start = startTagPositions.get(0);
int end = endTagPositions.get(0);
for (int i = 1; i < startTagPositions.size(); i++) {
if (end > startTagPositions.get(i)) end = endTagPositions.get(i);
else break;
}
System.out.println(fileText.substring(start, end+1));
startTagPositions.remove((Integer) start);
endTagPositions.remove((Integer) end);
}
} catch (IOException ignore) {
}
}
}