Як видалити або уникнути HTML-тегів в Android


81

PHP має strip_tagsфункцію, яка видаляє теги HTML і PHP із рядка.

Чи є у Android спосіб уникнути html?

Відповіді:


242

Рішення у відповіді , пов'язаний з допомогою @sparkymat зазвичай потрібні або регулярний вираз - яке є схильними помилками підходу - або встановлювати сторонні бібліотеки , такі як jsoup або Єрихон . Кращим рішенням для пристроїв Android є просто використання функції Html.fromHtml ():

public String stripHtml(String html) {
    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
       return Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY).toString();
    } else {
       return Html.fromHtml(html).toString();
    }
}

Тут використовується вбудований в Html парсер Android для побудови Spannedпредставлення вхідного html без будь-яких тегів html. Потім розмітка "Span" видаляється шляхом перетворення вихідних даних у рядок.

Як обговорювалося тут , поведінка Html.fromHtml змінилася з часу Android N. Докладнішу інформацію див. У документації .


5
Також зверніть увагу, Html.fromHtml(String)поверніть розширений клас CharSequence. Таким чином, ви можете використовувати його безпосередньо з методами, що приймають CharSequenceпараметри, без виклику toString(). Дякую Ніку за чудову відповідь :-)

4
Ви також можете використовувати, Html.escapeHtml(String)якщо ви просто хочете уникнути тегів, не видаляючи їх.
twaddington

1
Я думаю, що метод Html.fromHtml (String) має обмежені набори підтримки тегів
Hitesh Chavda

1
У моїй голові html є html> <head> <style> body {сімейство шрифтів: Verdana, sans-serif; розмір шрифту: 0.8em; колір: # 484848; } h1, h2, h3 {сімейство шрифтів: "Trebuchet MS", Verdana, sans-serif; поле: 0px; } h1 {розмір шрифту: 1.2em; } h2, h3 {розмір шрифту: 1.1em; } a, a: посилання, a: відвідано {color: # 2A5685;} a: hover, a: active {color: # c61a1a; } a.wiki-anchor {дисплей: немає; } год {ширина: 100%; висота: 1px; фон: #ccc; межа: 0; } .footer {font-size: 0.8em; стиль шрифту: курсив; } </style> </head> це також не обробляється. Pls help
png

4
Зверніть увагу, що Html.fromHtml(html).toString();прибирає кілька пробілів, що не завжди є вдалим вибором.
Бадді,

15

Вибачте за пізній допис, але я думаю, що це може допомогти іншим,

Щоб просто видалити HTML-смужки

Html.fromHtml(htmltext).toString()

Таким чином тег html буде замінено на рядок, але рядок не буде правильно відформатований. Звідси я і зробив

Html.fromHtml(htmltext).toString().replaceAll("\n", "").trim()

Таким чином я спочатку замінюю наступним рядком пробіли та видаляю порожній пробіл. Так само ви можете видалити інших.


Мені знадобилося 4 косих риски. Див Avis відповідь: stackoverflow.com/questions/18865393 / ...
Heinzlmaen

11

Ви також можете використовувати, Html.escapeHtml(String)якщо ви націлюєтесь на API 16 або вище.

Для того, щоб також орієнтуватися нижче API 16, ви можете замість цього використати наведений нижче клас, зателефонувавши, HtmlUtils.escapeHtml(String)який я просто витягнув з джерела Html.escapeHtml(String).

public class HtmlUtils {

    public static String escapeHtml(CharSequence text) {
        StringBuilder out = new StringBuilder();
        withinStyle(out, text, 0, text.length());
        return out.toString();
    }

    private static void withinStyle(StringBuilder out, CharSequence text,
                                    int start, int end) {
        for (int i = start; i < end; i++) {
            char c = text.charAt(i);

            if (c == '<') {
                out.append("&lt;");
            } else if (c == '>') {
                out.append("&gt;");
            } else if (c == '&') {
                out.append("&amp;");
            } else if (c >= 0xD800 && c <= 0xDFFF) {
                if (c < 0xDC00 && i + 1 < end) {
                    char d = text.charAt(i + 1);
                    if (d >= 0xDC00 && d <= 0xDFFF) {
                        i++;
                        int codepoint = 0x010000 | (int) c - 0xD800 << 10 | (int) d - 0xDC00;
                        out.append("&#").append(codepoint).append(";");
                    }
                }
            } else if (c > 0x7E || c < ' ') {
                out.append("&#").append((int) c).append(";");
            } else if (c == ' ') {
                while (i + 1 < end && text.charAt(i + 1) == ' ') {
                    out.append("&nbsp;");
                    i++;
                }

                out.append(' ');
            } else {
                out.append(c);
            }
        }
    }
}

Я використовую цей клас, який чудово працює.



4

Html.fromHtml може бути надзвичайно повільним для великих рядків html.

Ось як ви можете це зробити легко і швидко за допомогою jsoup:

Додайте цей рядок у файл gradle:

implementation 'org.jsoup:jsoup:1.11.3'

Перевірте останню версію jsoup тут: https://jsoup.org/download

Додайте цей рядок до свого коду:

String text = Jsoup.parse(htmlStr).text();

Перейдіть за цим посиланням, щоб дізнатися, як зберегти розриви рядків:

Як зберегти розриви рядків, використовуючи jsoup для перетворення html у звичайний текст?


2
 Spanned spanned;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            spanned = Html.fromHtml(textToShare, Html.FROM_HTML_MODE_LEGACY);
        } else {
            spanned = Html.fromHtml(textToShare);
        }
tv.setText(spanned.toString());


0

Оскільки про це ще не згадувалося, способом зробити це у зворотно сумісній манері буде використання утилітного класу HtmlCompat і просто виклик (з 0, якщо вам не потрібно використовувати конкретні прапори)

HtmlCompat.from(inputString, 0).toString()

Під капотом він уже виконує всі необхідні перевірки API для вас

if (Build.VERSION.SDK_INT >= 24) {
   return Html.fromHtml(source, flags);
}
return Html.fromHtml(source);

Отже для введення

<a href="https://www.stackoverflow.com">Click me!</a>

ви отримаєте лише рядок "Клацніть мене!" як вихід.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.