Начиная с Java 9, существует метод Matcher.replaceAll
, принимающий функцию обратного вызова в качестве параметра:
String text = "<ol start=\"3\">\n\t<li>Element 1</li>\n\t<li>Element 2</li>\n\t<li>Element 3</li>\n</ol>";
String result = Pattern
.compile("<ol start=\"(\\d)\">")
.matcher(text)
.replaceAll(m -> "<ol>" + repeat("\n\t<li style=\"visibility:hidden\" />",
Integer.parseInt(m.group(1))-1));
К repeat
строке, которую вы можете взять из здесь или использовать цикл.
public static String repeat(String s, int n) {
return new String(new char[n]).replace("\0", s);
}
После этого result
будет:
<ol>
<li style="visibility:hidden" />
<li style="visibility:hidden" />
<li>Element 1</li>
<li>Element 2</li>
<li>Element 3</li>
</ol>
Если вы застряли на более старой версии Java, вы все равно можете выполнить поиск и замену в два этапа.
Matcher m = Pattern.compile("<ol start=\"(\\d)\">").matcher(text);
while (m.find()) {
int n = Integer.parseInt(m.group(1));
text = text.replace("<ol start=\"" + n + "\">",
"<ol>" + repeat("\n\t<li style=\"visibility:hidden\" />", n-1));
}
Обновление от Andrea * ー テ ィ ー オ ー:
Я изменил (отличное) решение, приведенное выше, для включения также <ol>
, которые имеют несколько атрибутов, чтобы их тег не заканчивался на start
(например, <ol>
с буквами, такими как <ol start="4" style="list-style-type: upper-alpha;">
). При этом используется replaceAll
для работы с регулярным выражением в целом.
//Take something that starts with "<ol start=", ends with ">", and has a number in between
Matcher m = Pattern.compile("<ol start=\"(\\d)\"(.*?)>").matcher(htmlString);
while (m.find()) {
int n = Integer.parseInt(m.group(1));
htmlString = htmlString.replaceAll("(<ol start=\"" + n + "\")(.*?)(>)",
"<ol $2>" + StringUtils.repeat("\n\t<li style=\"visibility:hidden\" />", n - 1));
}