Lemis Lemis - 1 month ago 4x
HTML Question

Is it possible to use "$1" as argument for another method and place returned String on it's place in .replaceAll?

I'm writing tag->HTML parser - user type some text with custom tags (something between BB and Markdown, like

), then it's parsing to HTML - so
[#FF0000]red text[/#]
turns into
<span style='color:#FF0000;'>red text</strong>
and then placing in JTextPane with HTML style.

All user tags and HTML stores in HashMap and parsing like this:

public static String parseBBToHTML(String text) {
String html = text;

Map<String,String> bbMap = new HashMap<String , String>();

bbMap.put("\\[b\\]", "<strong>");
bbMap.put("\\[/b\\]", "</strong>");
bbMap.put("\\[color=(.+?)\\]", "<span style='color:$1;'>");
bbMap.put("\\[/color\\]", "</span>");

for (Map.Entry entry: bbMap.entrySet()) {
html = html.replaceAll(entry.getKey().toString(), entry.getValue().toString());

return html;

And then returned value used for .setText() in JTextPane with animation effect with other method, what just type one letter after other with pause between them.

All works good, but now I'm thinking about one thing:

I'm imitating pause in typing animation with empty HTML-tag like this:

So 10 "!" with pause in 20ms between them give me 200ms of pause.
I'm forming that "pause tags" with this method (it argument was int, but you'll see, why I use String now):

public static String pause(String ms){
String pausedText = "";
int time = Integer.parseInt(ms);
for (int i = 0; i < (time/animationSpeed); i++) {
pausedText = pausedText + "!";
return "<"+pausedText+">";

I want use tag like
for pause to 2000ms. So I just put in my parser string like this:

bbMap.put("\\[\\!(.+?)\\]", Dialogue.pause("$1"));

...and it didn't working. It's giving in method Dialogue.pause literally string "$1", not
as value of parsing.

How can I use
as argument to form "pause tag" and them place it in text?


A String is just a single, static value. What you want is a String which is dynamically computed from another String.

You need to change your Map from this:

Map<String, String> bbMap = new HashMap<String, String>();

to this:

Map<String, UnaryOperator<String>> bbMap = new HashMap<>();

A UnaryOperator<String> is a function that takes a String argument and returns a String value. So, you would populate your Map like this:

bbMap.put("\\[b\\]", s -> "<strong>");
bbMap.put("\\[/b\\]", s -> "</strong>");
bbMap.put("\\[color=(.+?)\\]", s -> "<span style='color:" + s + ";'>");
bbMap.put("\\[/color\\]", s -> "</span>");

bbMap.put("\\[\\!(.+?)\\]", s -> Dialogue.pause(s));

for (Map.Entry entry : bbMap.entrySet()) {
    StringBuffer buffer = new StringBuffer(html.length());

    Matcher matcher =
    while (matcher.find()) {
        String match =
            (matcher.groupCount() > 0 ? matcher.group(1) : null);
        String replacement = entry.getValue().apply(match);

    html = buffer.toString();