¿Cómo utilizar expresiones regulares para filtrar caracteres chinos en ORACLE?
Tomemos GB2312 como ejemplo para escribir una función que extraiga con precisión el chino simplificado. personajes de la mesa.
Supongamos que el juego de caracteres de la base de datos es GB2312, el juego de caracteres de la variable de entorno (registro u otro) también es GB2312
y los caracteres chinos guardados en la tabla también son GB2312
Entonces los caracteres chinos son de doble byte y el rango de codificación del chino simplificado es
B0A1 - F7FE
convertido a 10, y los caracteres chinos se pueden convertido a 10.
Convertido a decimal es
B0 A1 F7 FE
176, 161 - 247, 254
Veamos primero el asciistr Función Definición
Los caracteres que no son ASCII se convierten al formato \xxxx, donde xxxx representa UTF y xxxx representa la unidad de codificación UTF-16.
Pero esto no significa que los caracteres que comienzan con "\" sean caracteres chinos.
Ejemplo
SQLgt select * from test;
NOMBRE
-------- ------------
,ah OO10 ja
Hola aa
Hola a todos aa/
☆Ocean 123
★ABC
El quinto disco aquí tiene una sólida estrella de cinco puntas p >
Luego intente usar la función asciistr para convertir
SQLgt; seleccione nombre, asciistr(nombre) de la prueba;
NOMBRE ASCIISTR(NOMBRE)
------------------------------------------------
, ahOO10ha ,\554AOO10\54C8
Hola aa \4F60\597Daa
Hola a todos aa/ \5927\5BB6\597Daa/
☆Sea 123 \2606\ 5927\6D77123
★ABC \2605ABC
Podemos ver que la estrella sólida de cinco puntas también es sólida en el último registro. La estrella de cinco puntas también comienza con "\"
En este momento, no podemos usar el "\" que aparece en el asciistr (campo) para determinar si contiene caracteres chinos.
Mi función es la siguiente, la idea básica es determinar si la codificación del carácter está dentro del rango de codificación de caracteres chinos especificado en GB2312
[PHP]
Crear o reemplazar la función get_chinese(p_name en varchar2) return varchar2
as
v_code varchar2(30000) :=
v_chinese varchar2(4000) ) := ''
v_comma pls_integer
v_code_q pls_ entero
v_code_w pls_integer
comenzar
si p_name no es nulo entonces
seleccione reemplazar(substrb(dump(p_name, 1010), instrb(dump(p_name, 1010), 'ZHS16GBK: ')), 'ZHS16GBK: ', '' ) en v_code desde dual donde rownum=1;
para i en el bucle 1..length(p_name)
si lengthb( substr(p_name, i, 1))=2 entonces
v_comma := instrb(v_code,',');
v_code_q := to_number(substrb(v_code, 1, v_comma-1)); v_code_ w := to_number (substrb(v_code, v_comma 1, abs(instrb(v_code,',',1,2)-v_comma-1)));
if v_code_qgt;=176 and v_code_qlt; =247 y v_code_wgt ;=161 y v_code_wlt;=254 entonces
v_chinese:= v_chinese||substr(p_name,i,1);
end if;
v_code: = ltrim(v_code,' 1234567890');
v_code:= ltrim(v_code,',');
end if;
v_code:= ltrim (v_code,'1234567890');
v_code:= ltrim(v_code,',');
finalizar bucle;
devolver v_chinese ;
else
return '';
finalizar si
finalizar
/
.
[/PHP]
Bien, ahora ejecute algunas declaraciones
SQLgt select * from test;
NOMBRE
p>--------------------
,ah OO10 ha
Hola aa
Hola a todos aa/
☆Ocean 123
★A
BC
Se seleccionaron 5 registros.
1. Listar registros con caracteres chinos
SQLgt; seleccione el nombre de la prueba donde length(get_chinese(name) )gt; 0;
NOMBRE
--------------------
,ah OO10ha
Hola aa
Hola aa
Todos aa/
☆Hai 123
4 filas están seleccionadas.
2.
2. Enumere las líneas con caracteres chinos y solo las líneas con caracteres chinos. Listar filas con caracteres chinos y solo filas con caracteres chinos
SQLgt; select get_chinese(name) from test donde length(get_chinese(name))gt;
GET_CHINESE (NAME)
----- ---------------------------------- ---- ------------------------------
Ajá
Hola
Hola a todos
El mar
La fila 4 está seleccionada.
Cabe señalar que GB2312**** tiene 6763 caracteres, es decir, 72*94-5=6763
Lo que calculé aquí es 72*94, sin restar esos 5 caracteres nulos.
Los restaré cuando los encuentre
============
Reescribe esta función para extraer kanji o no kanji
Esta función tiene dos parámetros, el primero es la cadena que se va a extraer, el segundo es 1, que significa extraer un carácter chino, y no-1 significa extraer un carácter no chino
[PHP]
Crear o reemplazar la función get_chinese
(
p_name en varchar2,
p_chinese en varchar2
) Devuelve varchar2
como
v_code varchar2(30000):= '';
v_chinese varchar2(4000):= '';
v_non_chinese varchar2(4000):= '';
v_comma pls_integer
v_ code_q pls_integer
v_code_w pls_integer
comenzar
p>
si p_name no es nulo, entonces
seleccione reemplazar(substrb(dump(p_name, 1010), instrb(dump(p_name, 1010), 'ZHS16GBK: ')), 'ZHS16GBK : ' , '') en v_code desde dual donde rownum=1
para i en el bucle 1..length(p_name)
if lengthb(substr(p_name,i,1 )) =2 entonces
v_comma := instrb(v_code,',');
v_code_q := to_number(substrb(v_code, 1, v_comma-1));
p>
v_code_w:= to_number(substrb(v_code,v_comma 1,abs(instrb(v_code,',',1,2)-v_comma-1)));
Si v_code_qgt;= 176 y v_code_qlt;= 247 y v_code_wgt;=161 y v_code_wlt;=254 entonces
v_chinese:= v_chinese||substr(p_name,i,1);
else
v_non_chinese:= v_ non_chinese||substr(p_name,i,1);
end if;
v_code:= ltrim(v_code,'1234567890' );
v_code := ltrim(v_code,',');
else
v_non_chinese := v_non_chinese||substr(p_name, i, 1)
else
p>
terminar si;
v_code:= ltrim(v_code,'1234567890');
v_code:= ltrim(v_code,',');
p>
finaliza el bucle;
si p_chinese = '1' entonces
devuelve v_chinese;
si no
devuelve v_non_chinese;
finalizar si
else
devolver '';
finalizar si
final; p>
end p>
/
.
[/PHP]
SQLgt seleccione * de a;
NOMBRE
--------------------
Nosotros, ah,
él ( ai yah) es ★ellos
su \aah@
SQLgt;select * from a;
NOMBRE
---- ------ ----------
Nosotros, ah,
Él (ai yah) es ★ellos
suyo \aah@
SQLgt; seleccione get_chinese(nombre, 1) de a;
GET_CHINESE(NOMBRE, 1)
-------- ----- --------------------------
Estamos ah
Él es ah son ellos
Su ah
SQLgt; select get_chinese(name, 0) from a
GET_CHINESE(NAME, 0)
--- ----------------------------------
,
()★
\@
SQLgt;