2016-01-11 34 views
1

我需要檢測我的表是否有4字節的UTF-8字符,並刪除它們(如果有的話)。 我試過下面的SQL,但是它們返回錯誤ORA-12726: unmatched bracket in regular expression。所有括號都匹配,所以錯誤是不正確的。如何在Oracle DB中使用4字節的UTF-8字符選擇行?

select REGEXP_REPLACE(asdaasd', 
    '[' 
    || UTL_I18N.RAW_TO_CHAR ('010000', 'UTF8') 
    || '-' 
    || UTL_I18N.RAW_TO_CHAR ('01FFFF', 'UTF8') 
    || ']', '') 
from dual; 

select REGEXP_REPLACE('asdaasd', 
    '[' 
    || chr(to_number('010000', 'xxxxxx')) 
    || '-' 
    || chr(to_number('01FFFF', 'xxxxxx')) 
    || ']', '') 
from dual; 

這些查詢有什麼問題?

你知道如何按字符代碼點範圍查找行嗎?

回答

2

您可以使用the UNISTR function;該字符是codepoint U+2070E,UTF-16中的字符是D841DF0E。如文檔的註釋:

增補字符編碼爲兩個代碼單元,從高的替代物的第一範圍(U + D800到U + DBFF),和從低的替代物範圍內的第二(U + DC00至U + DFFF)。

這意味着你可以用它表示:

select unistr('\D841\DF0E') from dual; 

UNISTR('\D841\DF0E') 
-------------------- 

然後可以使用UNISTR來構建你的範圍:

select REGEXP_REPLACE('asdaasd', 
    '[' 
    || UNISTR('\D800\DC00') 
    || '-' 
    || UNISTR('\DBFF\DFFF') 
    || ']', '') 
from dual; 

REGEXP_REPLACE('ASDAASD','['||UNISTR('\D800\DC00')||'-'||UNISTR('\DBFF\DFFF')||']','') 
---------------------------------------------------------------------------------------- 
asdaasd 

假設你要排除所有增補字符;如果焦距更窄,則可以調整範圍。

2

也許這並不是你所需要的exacly但要解決錯誤ORA-12726使用此查詢

select REGEXP_REPLACE('asdaasd', 
    '\[' 
    || chr(to_number('010000', 'xxxxxx')) 
    || '-' 
    || chr(to_number('01FFFF', 'xxxxxx')) 
    || '\]', '') 
from dual; 
1

當你從原材料轉換成char必須在所選擇的編碼提供八位字節序列。你提供的是Unicode代碼點,但不是它們的utf8編碼。爲了得到這個,你可以使用在線工具,如this onecode table。例如。 U+010000在utf-8中表示爲(範圍擴展到U+010000 - U+02FFFF以包含源字符)。

所以在樣品的情況下,使用以下命令:

select REGEXP_REPLACE('asd'||UTL_I18N.RAW_TO_CHAR ('F0A09C8E', 'AL32UTF8')||'aasd', 
    '[' 
    || UTL_I18N.RAW_TO_CHAR ('F0908080', 'AL32UTF8') 
    || '-' 
    || UTL_I18N.RAW_TO_CHAR ('F0AFBFBF', 'AL32UTF8') 
    || ']', '') 
from dual; 
+0

謝謝。但是,即使將範圍中的第二個字符擴展到'F48083BF',它也不會取代該Unicode符號。輸出仍然是'asdaasd' – Barataliba

+0

@Barataliba要替換的字符不在指定的原始正則表達式的範圍之內,範圍擴展。 – collapsar

+1

Oracle字符集「UTF8」與通常已知的編碼[UTF-8](https://en.wikipedia.org/wiki/UTF-8)不同**。 Oracle字符集UTF8表示[CESU-8](https://en.wikipedia.org/wiki/CESU-8)編碼。對於「真正的」UTF-8,你必須使用Oracle字符集「AL32UTF8」,因此你必須使用'UTL_I18N.RAW_TO_CHAR(...,'AL32UTF8')' –

1

如果你喜歡RAW_TO_CHAR,你可以做這樣的:

SELECT REGEXP_REPLACE('asdaasd', 
    '[' 
    || UTL_I18N.RAW_TO_CHAR ('F0908080', 'AL32UTF8') 
    || '-' 
    || UTL_I18N.RAW_TO_CHAR ('F48FBFBF', 'AL32UTF8') 
    || ']', '') 
FROM dual; 

Oracle字符集UTF8是不一樣的俗稱編碼UTF-8。 Oracle字符集UTF8表示CESU-8編碼。對於UTF-8,您必須使用Oracle字符集AL32UTF8

U+01FFFF不是最大的Unicode碼點,您的字符串可能包含「」(U+02F8D3 CJK COMPATIBILITY IDEOGRAPH-2F8D3)。最大可能的Unicode代碼點是U+10FFFF,它等於UNISTR('\DBFF\DFFF')(由Alex Poole的答案提供), UTL_I18N.RAW_TO_CHAR ('F48FBFBF', 'AL32UTF8')

btw,轉換我使用此頁面:Unicode code converter

相關問題