作为前提,我有一个HTML文本,其中包含一些<ol>
元素。它们具有start
属性,但是我使用的框架无法在PDF转换期间解释它们。因此,我尝试应用的技巧是在开始时添加一些不可见的<li>
元素。
例如,假设此输入文本:
<ol start="3">
<li>Element 1</li>
<li>Element 2</li>
<li>Element 3</li>
</ol>
我想产生这个结果:
<ol>
<li style="visibility:hidden"></li>
<li style="visibility:hidden"></li>
<li>Element 1</li>
<li>Element 2</li>
<li>Element 3</li>
</ol>
因此,将n-1个不可见元素添加到有序列表中。 但是我无法从Java中以通用方式做到这一点。
假设示例中有确切的情况,我可以这样做(使用replace
,因此-老实说-没有正则表达式):
htmlString = htmlString.replace("<ol start=\"3\">",
"<ol><li style=\"visibility:hidden\"></li><li style=\"visibility:hidden\"></li>");
但是,显然,它仅适用于“ start = 3”的情况。我知道我可以使用组来提取“ 3”,但是如何将其用作“变量”以指定字符串<li style=\"visibility:hidden\"></li>
n-1次?
感谢您的任何见识。
答案 0 :(得分:4)
您不能使用正则表达式执行此操作,或者即使您发现某些破解方法也将是次佳的解决方案。
正确的方法是使用HTML解析库(例如Jsoup),然后将<li>
标签作为子元素添加到<ol>
,特别是使用{{3 }} 方法。 (使用Jsoup,您还可以读取start
属性值,以计算要添加的元素的数量)
答案 1 :(得分:3)
自Java 9开始,有一个Matcher.replaceAll
method taking a callback function作为参数:
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
字符串,您可以从here中获得技巧,也可以使用循环。
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ジーティーオー更新:
我修改了上面的(great)解决方案,其中还包含具有多个属性的<ol>
,以使它们的标签不以start
结尾(例如,<ol>
的字母为{ {1}})。这使用<ol start="4" style="list-style-type: upper-alpha;">
处理整个正则表达式。
replaceAll
答案 2 :(得分:1)
使用Jsoup,您可以编写如下内容:
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
class JsoupTest {
public static void main(String[] args){
String html = "<ol start=\"3\">\n" +
" <li>Element 1</li>\n" +
" <li>Element 2</li>\n" +
" <li>Element 3</li>\n" +
"</ol>"
+ "<p>some other html elements</p>"
+ "<ol start=\"5\">\n" +
" <li>Element 1</li>\n" +
" <li>Element 2</li>\n" +
" <li>Element 3</li>\n" +
" <li>Element 4</li>\n" +
" <li>Element 5</li>\n" +
"</ol>";
Document doc = Jsoup.parse(html);
Elements ols = doc.select("ol");
for(Element ol :ols){
int start = Integer.parseInt(ol.attr("start"));
for(int i=0; i<start-1; i++){
ol.prependElement("li").attr("style", "visibility:hidden");
}
ol.attributes().remove("start");
System.out.println(ol);
}
}
}
答案 3 :(得分:0)
您可以尝试一下。
$config
答案 4 :(得分:-2)
请使用java Matcher 和 Pattern 来计数 li 标记的出现,并使用 StringBuilder insert 方法以插入不可见的元素。
Matcher m = Pattern.compile("<li>").matcher(s);
while(m.find()){
++count;
}