Java特殊字符替换

5

我有一段文本:

“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.

当我尝试将电子邮件正文解析为text/plain时,我无法去掉“mostans=E1g = ism=E9t”中的=符号。请注意,HTML编码消息中缺少相同的字符。我不知道那个特殊字符可能是什么,但我需要消除它以恢复原始文本。
我尝试替换'\n',但不是这个字符。如果我在文本中按“Enter”,我可以正确地将其替换为任何我想要的字符。我还尝试了'\r'和'\t'。
所以问题是,我错过了什么?那个特殊字符来自哪里?是由于字符集和/或传输编码吗?如果是这样,我该怎么做才能解决问题并恢复原始文本。
欢迎任何帮助。
问候, Balázs
2个回答

3
你需要使用MimeUtility。这是一个示例:

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所说的那样,“quoted-printable”禁止编码行超过76个字符的长度。 - Emil
@Balázs Mária Németh:阅读有关 Quoted-printable 的内容。这将帮助您了解编码相关的知识。 - Emil
它可以工作。convertStreamToString 有点令人困惑,因为 InputStream output = MimeUtility.decode(stringStream, "quoted-printable"); 是关键,但是你的大部分答案都提到了上述方法 :) - Balázs Németh
@Emil:这并不是使用InputSupplier的正确方法。一个 InputSupplier 应该在每次调用它的 getInput() 方法时返回一个新的 InputStreamReader,或者其他什么东西。在这里,你的 InputSupplier 可能应该在其构造函数中接受一个 InputSupplier<?extends InputStream>。在 getInput() 中,它应该调用该供应商的 getInput(),然后使用 MimeUtility.decode 包装流并返回结果。然后,你可以将其与 Files.newInputStreamSupplier(File)一起使用。 - ColinD
@ColinD:我已经纠正了它。但我不太确定这是否是您在上面的评论中所指的。如果不正确,请检查并编辑它。 - Emil
显示剩余2条评论

2
传输编码“quoted-printable”禁止编码行超过76个字符的长度。如果要编码的文本包含更长的文本行,则必须插入“soft line break”,这由编码行的最后一个字符指示为单个“=”。这意味着以下换行符仅插入以满足76个字符限制,并且在解码传输编码时应删除以下换行符。

此外,换行符很可能是"\r\n",而不仅仅是"\r"或"\n"。 - Christoffer Hammarström
1
不仅可能,而且是必须的。在quoted-printable中,只允许使用CRLF(\r\n)换行符。 - jarnbjo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接