2017-01-10 36 views
6

Jak mogę usunąć znaki z ciągu, który nie jest obsługiwany przez utf8 character set MySQL? Innymi słowy, znaki o czterech bajtach, takie jak "", które są obsługiwane tylko przez MySQL's utf8mb4 character set.Jak mogę usunąć znaki, które nie są obsługiwane przez zestaw znaków utf8 MySQL?

Na przykład

C = -2.4‰ ± 0.3‰; H = -57‰ 

powinna stać

C = -2.4‰ ± 0.3‰; H = -57‰ 

Chcę załadować plik danych do tabeli MySQL, który ma CHARSET=utf8.

+0

Słyszałem, o co pytasz, ale dlaczego nie przekonwertować kolumny na "CHARACTER SET utf8mb4"? –

Odpowiedz

9

Kodowanie MySQL's utf8mb4 jest tym, co świat nazywa UTF-8.

Kodowanie MySQL to podzbiór UTF-8, który obsługuje tylko znaki w BMP (co oznacza znaki U + 0000 do U + FFFF włącznie).

Reference

Więc dodaje się dopasuje nieobsługiwane znaki w pytaniu:

/[^\N{U+0000}-\N{U+FFFF}]/ 

Oto trzy różne techniki można użyć oczyścić Twój wkład:

1: Usuń znaki nieobsługiwane:

s/[^\N{U+0000}-\N{U+FFFF}]//g; 

2: Re umieszczać znaki nieobsługiwane z U + fffd:

s/[^\N{U+0000}-\N{U+FFFF}]/\N{REPLACEMENT CHARACTER}/g; 

3: Wymień znaków nieobsługiwanych pomocą mapy tłumaczenie:

my %translations = (
    "\N{MATHEMATICAL ITALIC SMALL EPSILON}" => "\N{GREEK SMALL LETTER EPSILON}", 
    # ... 
); 

s{([^\N{U+0000}-\N{U+FFFF}])}{ $translations{$1} // "\N{REPLACEMENT CHARACTER}" }eg; 

Na przykład,

use utf8;        # Source code is encoded using UTF-8 
use open ':std', ':encoding(UTF-8)'; # Terminal and files use UTF-8. 

use strict; 
use warnings; 
use 5.010;    # say, // 
use charnames ':full'; # Not needed in 5.16+ 

my %translations = (
    "\N{MATHEMATICAL ITALIC SMALL EPSILON}" => "\N{GREEK SMALL LETTER EPSILON}", 
    # ... 
); 

$_ = "C = -2.4‰ ± 0.3‰; H = -57‰"; 
say; 

s{([^\N{U+0000}-\N{U+FFFF}])}{ $translations{$1} // "\N{REPLACEMENT CHARACTER}" }eg; 
say; 

wyjściowa:

C = -2.4‰ ± 0.3‰; H = -57‰ 
εC = -2.4‰ ± 0.3‰; εH = -57‰ 
+0

Jeśli dobrze rozumiem, muszę przekształcić znaki utf8 (np. 4-bajtowe znaki "") w BMP przed zastosowaniem Twojego wyrażenia regularnego. Czy istnieje funkcja do tego? –

+1

Nie wiem, co masz na myśli, przekształcając "" w BMP. BMP to zestaw znaków, który nie zawiera "". Możesz stworzyć mapowanie postaci spoza BMP do postaci wewnątrz BMP. Właśnie dodałem demonstrację tego do mojej odpowiedzi. – ikegami

+0

dziękuję za komentarz, ale miałem na myśli coś jeszcze: Chciałbym usunąć 4 bajty utf8 za pomocą twojego regex s/[^ \ N {U + 0000} - \ N {U + FFFF}] // g; Jednak gdy zastosuję go do mojego pliku (który zawiera "" zamiast jego reprezentacji BMP), 4-bajtowe znaki nie są odfiltrowywane. –

Powiązane problemy