【问题标题】:Convert plain text to HTML text in Java在 Java 中将纯文本转换为 HTML 文本
【发布时间】:2011-07-05 07:58:19
【问题描述】:

我有 java 程序,它将从服务器接收纯文本。纯文本可能包含 URL。 Java 库中是否有任何类可以将纯文本转换为 HTML 文本?还是其他图书馆?如果没有,那么解决办法是什么?

【问题讨论】:

  • 自己写很简单
  • 纯文本,根据定义,不能包含超链接。
  • @phihag 我会说这是纯文本:“www.google.com”
  • 您应该更准确地定义您的需求。纯文本是什么样的?您希望生成的 HTML 是什么样子的?
  • 别傻了。这很简单。 atamanroman 是对的。如果我在记事本中写入并保存http://www.google.com 并将其另存为文本,那就是纯文本。并且因为它包含一个超链接。我想将它作为链接呈现在JEditorPan 中。就是这样。

标签: java


【解决方案1】:

您应该以编程方式对文本进行一些替换。以下是一些线索:

  • 应将所有换行符转换为 "<br>\n"(\n 以提高输出的可读性)。
  • 应删除所有 CR(无论如何都使用 DOS 编码)。
  • 所有空格对都应替换为"  "
  • 将“"<"
  • 将“&”替换为"&"
  • 所有其他
  • 所有其他 >= 128 的字符应写为 "&#"+((int)myChar)+";",以使它们在每种编码中都可读。
  • 要自动检测您的链接,您可以使用像 "http://[^ ]+""www.[^ ]" 这样的正则表达式,然后像 JB Nizet 所说的那样转换它们。到"<a href=\""+url+"\">"+url+"</a>",但只有在完成所有其他替换之后。

执行此操作的代码如下所示:

public static String escape(String s) {
    StringBuilder builder = new StringBuilder();
    boolean previousWasASpace = false;
    for( char c : s.toCharArray() ) {
        if( c == ' ' ) {
            if( previousWasASpace ) {
                builder.append(" ");
                previousWasASpace = false;
                continue;
            }
            previousWasASpace = true;
        } else {
            previousWasASpace = false;
        }
        switch(c) {
            case '<': builder.append("&lt;"); break;
            case '>': builder.append("&gt;"); break;
            case '&': builder.append("&amp;"); break;
            case '"': builder.append("&quot;"); break;
            case '\n': builder.append("<br>"); break;
            // We need Tab support here, because we print StackTraces as HTML
            case '\t': builder.append("&nbsp; &nbsp; &nbsp;"); break;  
            default:
                if( c < 128 ) {
                    builder.append(c);
                } else {
                    builder.append("&#").append((int)c).append(";");
                }    
        }
    }
    return builder.toString();
}

但是,链接转换尚未添加。如果有人这样做,请更新代码。

【讨论】:

  • 好的。那我应该试试我自己的。
  • 抱歉,我没有想到这个简单的解决方案。状态机用于逆向情况,将 HTML 转换为纯文本,这有点困难。
  • 如果您只是在 HTML 中指定正确的编码,您可以跳过“encode chars > 128”。
  • 好答案-我基本上将其复制粘贴到我的代码中。令人惊讶的是,其中一个实用程序库(如 apache commons)中没有公共 API
  • 请注意,上面代码的 转义 部分可以通过调用 escapeHtml4 - commons.apache.org/proper/commons-lang/javadocs/api-3.4/org/… 来执行
【解决方案2】:

我找到了使用模式匹配的解决方案。这是我的代码 -

String str = "(?i)\\b((?:https?://|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,4}/)(?:[^\\s()<>]+|\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\))+(?:\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\)|[^\\s`!()\\[\\]{};:\'\".,<>?«»“”‘’]))";
Pattern patt = Pattern.compile(str);
Matcher matcher = patt.matcher(plain);
plain = matcher.replaceAll("<a href=\"$1\">$1</a>");

这里是输入和输出 -

输入文本可变plain:

some text and then the URL http://www.google.com and then some other text.

输出:

some text and then the URL <a href="http://www.google.com">http://www.google.com</a> and then some other text.

【讨论】:

    【解决方案3】:

    刚刚加入了所有答案的编码:

    private static String txtToHtml(String s) {
            StringBuilder builder = new StringBuilder();
            boolean previousWasASpace = false;
            for (char c : s.toCharArray()) {
                if (c == ' ') {
                    if (previousWasASpace) {
                        builder.append("&nbsp;");
                        previousWasASpace = false;
                        continue;
                    }
                    previousWasASpace = true;
                } else {
                    previousWasASpace = false;
                }
                switch (c) {
                    case '<':
                        builder.append("&lt;");
                        break;
                    case '>':
                        builder.append("&gt;");
                        break;
                    case '&':
                        builder.append("&amp;");
                        break;
                    case '"':
                        builder.append("&quot;");
                        break;
                    case '\n':
                        builder.append("<br>");
                        break;
                    // We need Tab support here, because we print StackTraces as HTML
                    case '\t':
                        builder.append("&nbsp; &nbsp; &nbsp;");
                        break;
                    default:
                        builder.append(c);
    
                }
            }
            String converted = builder.toString();
            String str = "(?i)\\b((?:https?://|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,4}/)(?:[^\\s()<>]+|\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\))+(?:\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\)|[^\\s`!()\\[\\]{};:\'\".,<>?«»“”‘’]))";
            Pattern patt = Pattern.compile(str);
            Matcher matcher = patt.matcher(converted);
            converted = matcher.replaceAll("<a href=\"$1\">$1</a>");
            return converted;
        }
    

    【讨论】:

    • 对于像www.stackoverflow.com这样的URL应该转换成http://www.stackoverflow.com
    【解决方案4】:

    使用这个

    public static String stringToHTMLString(String string) {
        StringBuffer sb = new StringBuffer(string.length());
        // true if last char was blank
        boolean lastWasBlankChar = false;
        int len = string.length();
        char c;
    
        for (int i = 0; i < len; i++) {
            c = string.charAt(i);
            if (c == ' ') {
                // blank gets extra work,
                // this solves the problem you get if you replace all
                // blanks with &nbsp;, if you do that you loss 
                // word breaking
                if (lastWasBlankChar) {
                    lastWasBlankChar = false;
                    sb.append("&nbsp;");
                } else {
                    lastWasBlankChar = true;
                    sb.append(' ');
                }
            } else {
                lastWasBlankChar = false;
                //
                // HTML Special Chars
                if (c == '"')
                    sb.append("&quot;");
                else if (c == '&')
                    sb.append("&amp;");
                else if (c == '<')
                    sb.append("&lt;");
                else if (c == '>')
                    sb.append("&gt;");
                else if (c == '\n')
                    // Handle Newline
                    sb.append("<br/>");
                else {
                    int ci = 0xffff & c;
                    if (ci < 160)
                        // nothing special only 7 Bit
                        sb.append(c);
                    else {
                        // Not 7 Bit use the unicode system
                        sb.append("&#");
                        sb.append(new Integer(ci).toString());
                        sb.append(';');
                    }
                }
            }
        }
        return sb.toString();
    }
    

    【讨论】:

      【解决方案5】:

      如果您的纯文本 URL(不同于包含 hyperlink ,正如您在问题中所写),然后将其转换为 HTML 中的超链接只需通过

      String hyperlink = "<a href='" + url + "'>" + url + "</a>";
      

      【讨论】:

      • 那不是字符串。那是带有 URL 的完全纯文本。 some text and then the URL http://www.google.com and then some other text.
      • 实际上,如果您将其呈现为 HTML,它将是一个链接。您应该阅读一些有关 HTML 的内容。
      • @Tanner - 你的意思是,如果我将 JEditorPan 的 htmltext 设置为纯文本,那么所有以 http://.... 开头的字符串都会是一个链接?
      • 没有。您的 JEditorPane 需要设置 html。然后它将任何文本呈现为 HTML。这意味着它将接受并呈现 HTML。

        等等。要显示一个链接,你需要将你的 URL 格式化为一个链接,这可以使用 JB Nizet 所说的格式来完成。 文本

      【解决方案6】:

      在 Android 应用程序中,我刚刚实现了内容的 HTMLifying(参见 https://github.com/andstatus/andstatus/issues/375)。实际转换是使用 Android 系统库在文字 3 行代码中完成的。这提供了在每个后续版本的 Android 库中使用更好实现的优势。

      private static String htmlifyPlain(String textIn) {
          SpannableString spannable = SpannableString.valueOf(textIn);
          Linkify.addLinks(spannable, Linkify.WEB_URLS);
          return Html.toHtml(spannable);
      }
      

      【讨论】:

        猜你喜欢
        • 2023-03-20
        • 2012-04-12
        • 2014-09-08
        • 2010-11-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-21
        • 1970-01-01
        相关资源
        最近更新 更多