【问题标题】:Java special chars replaceJava 特殊字符替换
【发布时间】:2011-05-08 10:19:00
【问题描述】:

我有一段文字: " Csuklási roham gyötörheti a svédeket, annyit emlegetik mostanság ismét a svéd modellt Magyarországon。"

在那个原始文本中根本没有换行符。

当我通过电子邮件发送此文本(使用 gmail)时,我将其编码如下:

Content-Type: text/plain; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable

Csukl=E1si roham gy=F6t=F6rheti a sv=E9deket, annyit emlegetik mostans=E1g =
ism=E9t a
sv=E9d modellt Magyarorsz=E1gon. 

在 HTML 中:

Content-Type: text/html; charset=ISO-8859-2
Content-Transfer-Encoding: quoted-printable


<span class=3D"Apple-style-span" style=3D"font-family: Helvetica, Verdana, = sans-serif; font-size: 15px; ">Csukl=E1si roham gy=F6t=F6rheti a sv=E9deket= , annyit emlegetik mostans=E1g ism=E9t a sv=E9d modellt Magyarorsz=E1gon.

....

当我尝试将电子邮件正文解析为文本/纯文本时,我无法摆脱“mostans=E1g =”中的 = 符号 ism=E9t" 在两个词之间。请注意,HTML 编码的消息中缺少相同的字符。我不知道那个特殊字符可能是什么,但我需要消除它才能取回原始文本。

我尝试替换'\n',但不是那个,如果我在文本中按'Enter',我可以正确地将它替换为我想要的任何字符。我也试过'\r'和'\t'。

所以问题是,我错过了什么?那个特殊字符是从哪里来的?是因为字符和/或传输编码吗?如果是这样,我该怎么做才能解决问题并取回原文。

欢迎任何帮助。

干杯, 巴拉兹

【问题讨论】:

    标签: java string email encoding


    【解决方案1】:

    你需要使用MimeUtility。这里是一个例子。

    public class Mime {
        public static void main(String[] args) throws MessagingException,
                IOException {
            InputStream stringStream = new FileInputStream("mime");
            InputStream output = MimeUtility.decode(stringStream,
                    "quoted-printable");
            System.out.println(convertStreamToString(output));
        }
    
        public static String convertStreamToString(InputStream is)
                throws IOException {
            /*
             * To convert the InputStream to String we use the Reader.read(char[]
             * buffer) method. We iterate until the Reader return -1 which means
             * there's no more data to read. We use the StringWriter class to
             * produce the string.
             */
            if (is != null) {
                Writer writer = new StringWriter();
    
                char[] buffer = new char[1024];
                try {
                    Reader reader = new BufferedReader(new InputStreamReader(is,
                            "ISO8859_1"));
                    int n;
                    while ((n = reader.read(buffer)) != -1) {
                        writer.write(buffer, 0, n);
                    }
                } finally {
                    is.close();
                }
                return writer.toString();
            } else {
                return "";
            }
        }
    }
    

    文件'mime'包含编码文本:

    Csukl=E1si roham gy=F6t=F6rheti a sv=E9deket, annyit emlegetik mostans=E1g =
    ism=E9t a
    sv=E9d modellt Magyarorsz=E1gon.
    

    更新:

    使用Guava 库:

        InputSupplier<InputStream> supplier = new InputSupplier<InputStream>() {
            @Override
            public InputStream getInput() throws IOException {
                InputStream inStream = new FileInputStream("mime");
                InputStream decodedStream=null;
                try {
                    decodedStream = MimeUtility.decode(inStream,
                    "quoted-printable");
                } catch (MessagingException e) {
                    e.printStackTrace();
                }
                return decodedStream;
            }
        };
        InputSupplier<InputStreamReader> result = CharStreams
        .newReaderSupplier(supplier, Charsets.ISO_8859_1);
        String ans = CharStreams.toString(result);
        System.out.println(ans);
    

    【讨论】:

    • @Balázs Mária Németh:是的,它已被消除,但我看到原始文本中没有额外的换行符。也许就像 jarnbjo 所说的那样,“引用打印”禁止编码行超过长度为 76 个字符。
    • @Balázs Mária Németh:了解Quoted-printable。这将帮助您了解编码。
    • 它有效。 convertStreamToString 有点混乱,因为 InputStream output = MimeUtility.decode(stringStream, "quoted-printable");是关键,但你的大部分答案是上面提到的方法:)
    • @Balázs Mária Németh:你还得到了一个额外的换行符吗?
    • 我错了,我可以看到那些多余的行,是的!所以这意味着我同时拥有\n和\r\n,而后者才是真正的?
    【解决方案2】:

    传输编码“quoted-printable”禁止编码的行长度超过 76 个字符。如果要编码的文本包含较长的文本行,则必须插入“软换行符”,它由单个“=”表示,作为编码行的最后一个字符。这意味着插入以下换行符只是为了满足76个字符的限制,并且在解码传输编码时应该删除以下换行符。

    【讨论】:

    • 补充一点,换行符很可能是“\r\n”,而不仅仅是“\r”或“\n”。
    • 这不仅是可能的,而且是强制性的。在quoted-printable 中只允许使用 CRLF (\r\n) 换行符。
    最近更新 更多