Regex: wie eine Zeichenfolge mit n Auftreten eines Teils ersetzen

Andrea:

Als Prämisse, habe ich einen HTML - Text, mit einigen <ol>Elementen. Diese haben ein startAttribut, aber der Rahmen verwende ich nicht in der Lage , sie während einer PDF - Konvertierung zu interpretieren. So ist der Trick , den ich anwenden versuche ist eine Reihe von unsichtbaren hinzufügen <li>Elemente am Anfang.

Als ein Beispiel: Angenommen, diesen Eingabetext:

<ol start="3">
   <li>Element 1</li>
   <li>Element 2</li>
   <li>Element 3</li>
</ol>

Ich möchte dieses Ergebnis liefern:

<ol>
   <li style="visibility:hidden"></li>
   <li style="visibility:hidden"></li>
   <li>Element 1</li>
   <li>Element 2</li>
   <li>Element 3</li>
</ol>

Also, Zugabe von n-1 unsichtbare Elemente in die geordnete Liste. Aber ich bin nicht in der Lage, dass von Java in einer verallgemeinerten Art und Weise zu tun.

Den genauen Fall im Beispiel Angenommen, könnte ich dies tun (mit replace, so - um ehrlich zu sein - ohne regulären Ausdrücke):

htmlString = htmlString.replace("<ol start=\"3\">",
            "<ol><li style=\"visibility:hidden\"></li><li style=\"visibility:hidden\"></li>");

Aber natürlich, gilt nur für den Fall mit „start = 3“. Ich weiß , dass ich Gruppen kann die „3“, zu extrahieren , aber wie kann ich es als eine „Variable“ verwenden , um die Zeichenfolge angeben , <li style=\"visibility:hidden\"></li>n-1 Anzahl der Zeiten? Vielen Dank für jede Einsicht.

tobias_k:

Da Java 9, gibt es ein Matcher.replaceAllVerfahren zur Herstellung einer Callback - Funktion nimmt als Parameter:

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));      

Um repeatdie Zeichenfolge können Sie den Trick aus nehmen hier oder eine Schleife verwenden.

public static String repeat(String s, int n) {
    return new String(new char[n]).replace("\0", s);
}

Danach resultist:

<ol>
    <li style="visibility:hidden" />
    <li style="visibility:hidden" />
    <li>Element 1</li>
    <li>Element 2</li>
    <li>Element 3</li>
</ol>   

Wenn Sie mit einer älteren Version von Java stecken geblieben sind, können Sie immer noch in zwei Schritten anzupassen und ersetzen.

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));
}

Aktualisieren von Andrea Gee Tee O:

I modifiziert , um die (große) -Lösung oben auch für die Aufnahme , <ol>die mehrere Attribute haben, so dass ihre nicht - Tag am Ende mit start(beispielsweise <ol>mit Buchstaben, wie <ol start="4" style="list-style-type: upper-alpha;">). Diese Anwendungen replaceAllmit Regex als Ganzes zu behandeln.

//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));
}

Ich denke du magst

Origin http://43.154.161.224:23101/article/api/json?id=119975&siteId=1
Empfohlen
Rangfolge