[英]remove non-UTF-8 characters from xml with declared encoding=utf-8 - Java
我必須在Java中處理這種情況:
我從聲明為encoding = utf-8的客戶端獲取XML格式的請求。 不幸的是,它可能不包含utf-8字符,並且需要從我這邊的xml中刪除這些字符(遺留)。
讓我們考慮這個無效XML包含£(磅)的示例。
1)我得到xml作為帶有£的java字符串(我現在無法訪問接口,但我可能將xml作為java字符串)。 我可以使用replaceAll(£,“”)來擺脫這個角色嗎? 任何潛在的問題?
2)我得到xml作為字節數組 - 在這種情況下如何安全地處理這個操作?
1)我得到xml作為帶有£的java字符串(我現在無法訪問接口,但我可能將xml作為java字符串)。 我可以使用replaceAll(£,“”)來擺脫這個角色嗎?
我假設你想要擺脫非ASCII字符,因為你在談論一個“遺產”方面。 您可以使用以下正則表達式刪除可打印ASCII范圍之外的任何內容:
string = string.replaceAll("[^\\x20-\\x7e]", "");
2)我得到xml作為字節數組 - 在這種情況下如何安全地處理這個操作?
您需要將byte[]
包裝在ByteArrayInputStream
,以便您可以使用InputStreamReader
在UTF-8編碼的字符流中讀取它們,其中您指定編碼,然后使用BufferedReader
逐行讀取它。
例如
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes), "UTF-8"));
for (String line; (line = reader.readLine()) != null;) {
line = line.replaceAll("[^\\x20-\\x7e]", "");
// ...
}
// ...
UTF-8是一種編碼; Unicode是一個字符集。 但GBP符號絕對是Unicode字符集,因此絕對可以用UTF-8表示。
如果你確實意味着UTF-8,並且你實際上試圖刪除不是UTF-8中字符的有效編碼的字節序列,那么......
CharsetDecoder utf8Decoder = Charset.forName("UTF-8").newDecoder();
utf8Decoder.onMalformedInput(CodingErrorAction.IGNORE);
utf8Decoder.onUnmappableCharacter(CodingErrorAction.IGNORE);
ByteBuffer bytes = ...;
CharBuffer parsed = utf8Decoder.decode(bytes);
...
"test text".replaceAll("[^\\u0000-\\uFFFF]", "");
此代碼從string中刪除所有4字節的utf8字符。在執行Mysql innodb varchar條目時,這可能需要用於某些目的
我從本地目錄中讀取文件時遇到了同樣的問題,並嘗試了這個:
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "UTF-8"));
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document xmlDom = db.parse(new InputSource(in));
您可能必須使用網絡輸入流而不是FileInputStream。
- 卡皮爾
請注意,第一步應該是您要求XML的創建者(最有可能是本地“僅打印數據”XML生成器)在發送給您之前確保其XML正確無誤。 如果他們使用Windows,最簡單的測試是要求他們在Internet Explorer中查看它,並在第一個違規字符處查看解析錯誤。
雖然他們解決了這個問題,但你可以簡單地編寫一個改變標題部分的小程序來聲明編碼是ISO-8859-1:
<?xml version="1.0" encoding="iso-8859-1" ?>
並保持其余部分不受影響。
在java機器上將字節數組轉換為String后,您將獲得(默認情況下在大多數機器上)UTF-16編碼的字符串。 擺脫非UTF-8字符的正確解決方案是使用以下代碼:
String[] values = {"\\xF0\\x9F\\x98\\x95", "\\xF0\\x9F\\x91\\x8C", "/*", "look into my eyes 〠.〠", "fkdjsf ksdjfslk", "\\xF0\\x80\\x80\\x80", "aa \\xF0\\x9F\\x98\\x95 aa"};
for (int i = 0; i < values.length; i++) {
System.out.println(values[i].replaceAll(
"[\\\\x00-\\\\x7F]|" + //single-byte sequences 0xxxxxxx
"[\\\\xC0-\\\\xDF][\\\\x80-\\\\xBF]|" + //double-byte sequences 110xxxxx 10xxxxxx
"[\\\\xE0-\\\\xEF][\\\\x80-\\\\xBF]{2}|" + //triple-byte sequences 1110xxxx 10xxxxxx * 2
"[\\\\xF0-\\\\xF7][\\\\x80-\\\\xBF]{3}" //quadruple-byte sequence 11110xxx 10xxxxxx * 3
, ""));
}
或者如果你想驗證某些字符串是否包含非utf8字符,你可以使用Pattern.matches:
String[] values = {"\\xF0\\x9F\\x98\\x95", "\\xF0\\x9F\\x91\\x8C", "/*", "look into my eyes 〠.〠", "fkdjsf ksdjfslk", "\\xF0\\x80\\x80\\x80", "aa \\xF0\\x9F\\x98\\x95 aa"};
for (int i = 0; i < values.length; i++) {
System.out.println(Pattern.matches(
".*(" +
"[\\\\x00-\\\\x7F]|" + //single-byte sequences 0xxxxxxx
"[\\\\xC0-\\\\xDF][\\\\x80-\\\\xBF]|" + //double-byte sequences 110xxxxx 10xxxxxx
"[\\\\xE0-\\\\xEF][\\\\x80-\\\\xBF]{2}|" + //triple-byte sequences 1110xxxx 10xxxxxx * 2
"[\\\\xF0-\\\\xF7][\\\\x80-\\\\xBF]{3}" //quadruple-byte sequence 11110xxx 10xxxxxx * 3
+ ").*"
, values[i]));
}
如果你有可用的字節數組,你可以更正確地過濾它們:
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes), "UTF-8"));
for (String currentLine; (currentLine = bufferedReader.readLine()) != null;) {
currentLine = currentLine.replaceAll(
"[\\x00-\\x7F]|" + //single-byte sequences 0xxxxxxx
"[\\xC0-\\xDF][\\x80-\\xBF]|" + //double-byte sequences 110xxxxx 10xxxxxx
"[\\xE0-\\xEF][\\x80-\\xBF]{2}|" + //triple-byte sequences 1110xxxx 10xxxxxx * 2
"[\\xF0-\\xF7][\\x80-\\xBF]{3}" //quadruple-byte sequence 11110xxx 10xxxxxx * 3
, ""));
}
要使整個Web應用程序兼容UTF8,請在此處閱讀:
如何讓UTF-8在Java webapps中工作
有關字節編碼和字符串的更多信息 。
你可以在這里查看你的模式。
這里的 PHP也一樣。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.