首页 > 解决方案 > 性格问题

问题描述

返回故事

我基本上从数据库中检索字符串。我更改了一些文本或那些字符串。然后我将这些字符串上传回数据库,替换原始字符串。查看显示这些字符串的前端后,我注意到了字符问题。我不再有原始字符串,但我确实有更新的字符串。

问题

这些字符串中包含来自其他语言的字符。它们现在无法正确显示。我查看了代码点,原来的章程似乎是一个代码点,现在是两个不同的代码点。

"Je?ro^me" //code-points 8. Code-points: 74, 101, 63, 114, 111, 94, 109, 101
"Jéróme" //code-points 6.   Code-points: 74,   233,   114,    243,  109, 101 

问题

我怎么"Je?ro^me"回去"Jéróme"

我尝试过的事情

  1. 使用 Notepad++ 将编码转换为UTF8ANSIWINDOWS-1252.
  2. 创建了一个 Map 来查找类似的东西e?并将它们转换为é.

两个尝试解决问题的问题

一种。尝试不同的转换后问题仍然存在。

湾。这里有两个问题:

  1. 我不知道要寻找的所有潜力e?,等。o^有超过 20,000 个文件可能涵盖多种语言。
  2. 如果我有一个以结尾的句子怎么办e?

我研究了一些东西以更好地理解这个问题

  1. 什么是 Java 中的“代理对”?
  2. https://docs.oracle.com/javase/tutorial/i18n/text/supplementaryChars.html
  3. https://www.w3.org/International/questions/qa-what-is-encoding
  4. https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/

MCVE

import java.util.HashMap;
import java.util.Map;

/**
 *https://stackoverflow.com/questions/5903008/what-is-a-surrogate-pair-in-java
 *https://docs.oracle.com/javase/tutorial/i18n/text/supplementaryChars.html
 *https://www.w3.org/International/questions/qa-what-is-encoding
 *https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/
 * @author sedri
 */
public class App {
    
    static String outputString; 
    
    public static void main(String[] args) {
        
        //May approach to fix the issue
        //Use a map to replace string issue with the correct character
        //The output looks good, but I would need to include all special characters for many languages.
        //What if I have a sentence like: How old are thee? 
        Map<String, String> map = new HashMap();
        map.put("e?", "é");
        map.put("o^", "ó");
        
        final String string = "Je?ro^me";
        final String accentString = "Jéróme";
        outputString = string;
        map.forEach((t, u) -> {
            if(outputString.contains(t))
            {
                outputString = outputString.replace(t, u);
            }
        });
        System.out.println("Fixed output: " + outputString);        
        System.out.println("");                    
        //End of my attempt at a solution.
        
        System.out.println("code points: " + string.codePoints().count());                
        for(int i = 0; i < string.length(); i++)
        {
            System.out.println(string.charAt(i) + ": " + Character.codePointAt(string, i));
        }
        System.out.println("");    
        
        System.out.println("code points: " + accentString.codePoints().count());                
        for(int i = 0; i < accentString.length(); i++)
        {
            System.out.println(accentString.charAt(i) + ": " + Character.codePointAt(accentString, i));
        }
        System.out.println("");    
          
        System.out.println("code points: " + outputString.codePoints().count());  
        for(int i = 0; i < outputString.length(); i++)
        {
            System.out.println(outputString.charAt(i) + ": " + Character.codePointAt(outputString, i));
        }        
        System.out.println("");  
    }
}

标签: javacharacter-encodingcodepoint

解决方案


您的代码点之一是 63(一个问号)这一事实意味着您将无法可靠地将该数据恢复为原始格式。可以代表许多未正确解码的?不同字符,这意味着您丢失了恢复原始字符的重要信息。

您需要做的是建立正确的编码,以便在您首先从数据库中读取数据时使用。由于您尚未在读取这些字符串的位置发布代码,因此我无法准确告诉您如何或在何处执行此操作。

希望数据库本身的数据还没有被错误的字符编码损坏,否则你已经丢失了你需要的信息。

您可以通过将“o^”替换为“ó”之类的操作来部分修复此类损坏,但是如果“è”和“é”都变成“e?”,您永远无法确定哪个是哪一个。


推荐阅读