keep html, css, javascript or anything <between-these-brackets> unchanged and rest to be converted in ASCII Characters

Viewed 111

I want to keep HTML, CSS, JS or whatever inside as it is and to convert the text resides outside these brackets into ASCII Characters.

For example looking for: <b>Hello World</b>
Required output is: <b> &#72;&#101;&#108;&#108;&#111; &#87;&#111;&#114;&#108;&#100; </b>

What I experimented so far is: I applied ASCII Characters with java code e.g.: str.replace("H", "&#72;") but certainly it's changing both inside and outside tags as:

&#60;&#98;&#62;     &#72;&#101;&#108;&#108;&#111; &#87;&#111;&#114;&#108;&#100; &#60;/&#98;&#62;

It prints only <b>Hello World</b> rather then applying as html code.

I am looking for the solution to keep html, css, javascript or anything unchanged and rest to be converted in ASCII Characters

Please NOTE: Hello World is dynamic value

2 Answers

You can use the regex, (?<=>)([^<]*)(?=<) to find the text between HTML tags. After extracting the text, you can split it on each character and then cast each character into int in order to get its ASCII value.

import java.util.Arrays;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        String str = "<b>Hello World</b>";
        System.out.println(convert(str));
    }

    static String convert(String str) {
        String regex = "(?<=>)([^<]*)(?=<)";

        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        if (matcher.find()) {
            String match = matcher.group();
            if (!match.isBlank()) {
                return str.replaceAll(regex,
                        " " + Arrays.stream(match.split(""))
                                .map(s -> !" ".equals(s) ? ("&#" + (int) Character.valueOf(s.charAt(0)) + ";") : " ")
                                .collect(Collectors.joining()) + " ");
            }
        }

        return str;
    }
}

Output:

<b> &#72;&#101;&#108;&#108;&#111; &#87;&#111;&#114;&#108;&#100; </b>

Explanation of the regex by regex101.com:

enter image description here

JSoup does the job nicely and efficiently, with the least amount of code needed:

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class Parser {
    public static void main(String[] args) {
        String html = "<b>Hello World!</b>";
        Document doc = Jsoup.parse(html);
        Elements elements = doc.select("*:not(html):not(head):not(body)");
        for(Element e : elements) {
            String tagName = e.tagName();
            if(!tagName.equals("#root")) {
                System.out.println("<"+tagName+">"+convertToAscii(e.html())+"</"+tagName+">");
            }
        }
    }
    public static String convertToAscii(String text) {
        StringBuilder str = new StringBuilder();
        int len = text.length();
        for(int i = 0; i < len; i++) {
            str.append("&#"+(int)text.charAt(i)+";");
        }
        return str.toString();
    }
}

Which prints:

<b>&#72;&#101;&#108;&#108;&#111;&#32;&#87;&#111;&#114;&#108;&#100;&#33;</b>

Import JSoup in pom.xml:

<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.13.1</version>
</dependency>
Related