正規表現:部分文字列のn個出現した文字列を置換する方法

アンドレア:

前提として、私はいくつかと、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>");

しかし、明らかに、それだけで「開始= 3」の場合に適用されます。私は「3」を抽出するためにグループを使用することができます知っているが、どのように私は、文字列を指定し、「変数」として使用することができます<li style=\"visibility:hidden\"></li>のn-1倍の数を?任意の洞察力をありがとう。

tobias_k:

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

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

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=119979&siteId=1