Ho bisogno di un trucco per la codifica dei caratteri per eliminare i segni di accento ebraico.
Campione prima
בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ
Esempio dopo
בראשית ברא אלהים את השמים ואת הארץ
Ho bisogno di un trucco per la codifica dei caratteri per eliminare i segni di accento ebraico.
Campione prima
בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ
Esempio dopo
בראשית ברא אלהים את השמים ואת הארץ
Risposte:
Il trucco qui è rendersi conto che questi personaggi che vedi nella domanda con gli "accenti" non sono davvero i personaggi (cioè "Questi non sono idroidipersonaggi che stai cercando ";-)). Gli" accenti "sono vari tipi di notazioni che indicano cose come:
vocali (linee e punti che sono in genere sotto le lettere):
pronuncia (punti che di solito sono dentro o sopra le lettere):
punteggiatura
Le lettere ebraiche effettive sono ciò che viene mostrato nella versione ridotta (ovvero il risultato finale di ciò che viene richiesto qui). Ciò a cui ci riferiamo qui come "accenti" sono noti come segni diacritici. L'articolo di Wikipedia sui segni diacritici ebraici contiene molte buone informazioni su questi marchi, tra cui la seguente immagine e didascalia:
Gen. 1: 9 E Dio disse: "Lasciate che le acque siano raccolte". Lettere in nero, punta in rosso, cantillazione in blu
Passare da quei personaggi di base a ciò che mostra la prima riga (con le vocali, ecc.) È una questione di aggiungere uno o più "accenti". Unicode (UTF-16 in SQL Server, sebbene l'interpretazione predefinita gestisca solo i punti di codice UCS-2 / Basic Multilingual Plane (BMP)) consente ad alcuni caratteri di sovrapporre un altro carattere non sovrapposto quando adiacenti ad essi. Questi sono conosciuti come Combinare personaggi .
Senso:
SELECT DATALENGTH(N'מַ֖'); -- character taken from original given text
Ritorna:
6
non 2
come la maggior parte delle persone si aspetterebbe di vedere un singolo carattere a doppio byte. Quindi forse proviamo a trovare quale personaggio è lì facendo:
SELECT UNICODE(N'מַ֖');
che ritorna:
1502
Naturalmente, le funzioni UNICODE
e ASCII
restituiscono solo il INT
valore del primo carattere di qualunque stringa venga loro assegnata. Ma un valore di 1502 copre solo 2 byte, il che lascia 4 byte non considerati. Guardando i valori binari / esadecimali dello stesso "personaggio" ebraico:
SELECT NCHAR(1502), CONVERT(BINARY(2), UNICODE(N'מַ֖')), CONVERT(VARBINARY(10), N'מַ֖');
noi abbiamo:
מ
0x05DE 0xDE05B7059605
Ora, 0x05DE è la rappresentazione esadecimale di 1502 e il 1502 è solo il " מ ". La parte successiva può essere separata in tre set da 2 byte: DE05 B705 9605 . Ora, i valori di stringa Unicode sono memorizzati in Little Endian, il che significa che l'ordine dei byte è invertito. Se cambiamo ciascuno di questi tre set otteniamo:
05DE (il carattere di base) 05B7 0596 (il non rappresentato per 4 byte).
Ok. Quindi cosa succede se rimuoviamo quel personaggio base?
SELECT REPLACE(N'מַ֖' COLLATE Hebrew_BIN2, NCHAR(1502) COLLATE Hebrew_BIN2, '');
Ciò restituisce i due caratteri rimanenti (non è facile da vedere qui, quindi ho fatto della riga seguente un'intestazione per aumentare la dimensione del carattere; puoi anche eseguire quanto sopra REPLACE
per vederli):
Quindi, dobbiamo eliminare ogni singolo punto di codice che è uno di questi caratteri "extra" combinati (disponibile su: http://unicode-table.com/en/search/?q=hebrew ) e che ci lascerà con i personaggi di base. Possiamo farlo tramite:
CREATE FUNCTION dbo.RemoveHebrewAccents (@txeTwerbeH NVARCHAR(MAX))
RETURNS NVARCHAR(MAX)
WITH SCHEMABINDING
AS
BEGIN
WITH base (dummy) AS
(
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
), nums AS
(
-- we will want to generate code points 1425 - 1479
SELECT TOP (55) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS [Num]
FROM base b1
CROSS JOIN base b2
)
SELECT @txeTwerbeH = REPLACE(
@txeTwerbeH COLLATE Hebrew_BIN2,
NCHAR(1424 + nums.[Num]) COLLATE Hebrew_BIN2,
''
)
FROM nums;
RETURN @txeTwerbeH;
END;
E quindi possiamo provarlo con il testo originale come segue:
DECLARE @Hebrew NVARCHAR(200) = N'בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ';
SELECT dbo.RemoveHebrewAccents(@Hebrew);
Ritorna:
Note aggiuntive:
Tecnicamente, esiste un set di punti di codice tra 64298 e 64334 che ne hanno alcuni vocali e "accenti" di pronuncia incorporati nel personaggio. Se questi devono essere gestiti, questo può essere un secondo passo nella funzione per fare una semplice sostituzione di quei caratteri.
Sembra che questi punti di accento, punteggiatura, ecc. Coincidano solo quando si usano le regole di confronto binarie. Anche usando Hebrew_100_CS_AS_KS_WS_SC
non li ha abbinati. Ma il seguente ha funzionato: Hebrew_BIN
, Hebrew_BIN2
, Latin1_General_BIN
, e Latin1_General_BIN2
. Nella funzione ho finito per usare Hebrew_BIN2
. Si noti che quando si utilizzano le regole di confronto binarie, a meno che non si abbia una necessità specifica di utilizzare le _BIN
regole di confronto precedenti , è necessario utilizzare solo le _BIN2
regole di confronto più recenti .
Per chiunque sia curioso, il testo di esempio ebraico è in realtà Bereishis 1: 1 (che è anche la prima parola sul lato destro poiché l'ebraico viene letto da destra a sinistra; in inglese sarebbe "Genesi 1: 1" anche se quella non è una traduzione diretta della parola, solo il nome del primo libro della Torah / Bibbia; la traduzione diretta è "all'inizio"):
All'inizio della creazione di Dio nei cieli e nella Terra
19/01/2015: ho trovato delle risorse straordinarie che spiegano sia la combinazione di personaggi che il set di caratteri ebraico:
Questo è un problema interessante, e ho dovuto affrontare un po 'di tempo lavorando con personaggi giapponesi. Ho colpito un po 'di un muro di mattoni nel tentativo di individuare i personaggi problematici, anche se spero che questo ti porti da qualche parte a trovarli.
Per prima cosa ho messo tutti gli NCHAR in un tavolo:
SET NOCOUNT ON
DECLARE @cnt INT = 1
DECLARE @sqlcmd NVARCHAR(512) = ''
CREATE TABLE #CHARS (
[CharOrder] INT IDENTITY(1,1) PRIMARY KEY CLUSTERED,
[Result] NVARCHAR(4)
)
WHILE @cnt < 65536
BEGIN
SELECT @sqlcmd = '
INSERT #CHARS
([Result] )
SELECT NCHAR(' + CAST(@cnt AS NVARCHAR) + ')
'
EXEC sys.sp_executesql @sqlcmd
SET @cnt +=1
END
Quindi ho individuato uno dei caratteri non accentati:
SELECT c.CharOrder, c.Result
FROM #CHARS AS c
WHERE c.Result = N'ר'
ORDER BY c.CharOrder
Quindi ho trovato la gamma di caratteri in cui si trovano i personaggi ebraici:
SELECT c.CharOrder, c.Result
FROM #CHARS AS c
WHERE c.CharOrder >= 1488
AND c.CharOrder < 1523
ORDER BY c.CharOrder
Ma cercando di trovare i caratteri accentati che desideri, non sembrano comparire, tranne un colpo al codice 8501.
SELECT c.CharOrder ,
c.Result
FROM #CHARS AS c
WHERE c.Result IN ( N'רֵ', N'א', N'שִׁ֖', N'י', N'ת', N'בְּ', N'בָּ', N'רָ֣',
N'א', N'אֱ', N'לֹ', N'הִ֑', N'י', N'ם', N'אֵ֥', N'ת',
N'הַ', N'שָּׁ', N'מַ֖', N'יִ', N'ם', N'וְ', N'אֵ֥', N'ת',
N'הָ', N'אָֽ', N'רֶ', N'ץ' )
ORDER BY c.CharOrder
Quindi, solo guardando i personaggi circostanti, non riesco davvero a identificare altre corrispondenze al tuo testo.
SELECT c.CharOrder, c.Result
FROM #CHARS AS c
WHERE c.CharOrder >= 8499
AND c.CharOrder < 8539
ORDER BY c.CharOrder
Molti di loro sembrano essere lanciati come quei piccoli rettangoli nebulosi di qualunque cosa.
Ancora una volta, scusa non è una soluzione, ma spero che sia di aiuto.
Ho usato una tabella dei numeri. Ci sono molti post che spiegano di cosa si tratta, perché sono utili e come ottenerne uno in modo efficiente.
Non utilizzo alcuna funzionalità integrata per convertire i caratteri accentati in equivalenti non accentati. Invece, creo un elenco di ricerca che popolerai con le conversioni richieste. Dovrai utilizzare nvarchar
e definire le tue traduzioni comeN'x'
, ovviamente.
Grazie a questo post per il suggerimento di concatenazione delle righe.
drop table #Numbers;
select
*
into #Numbers
from
(
select *
from (values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11)) as T(N)
) as xx;
drop table #Lookups;
select
*
into #Lookups
from
(
select *
from (values ('a','m'),('b','n'),('c','o'),('d','p'),('e','q'),('m','z')) as T(CharFrom,CharTo)
) as xx;
drop table #Inputs;
select
*
into #Inputs
from
(
select *
from (values ('abcdefghi')
,('abtcd')
) as T(Word)
) as xx;
select
ix.Word as Original
,(
select
Coalesce(l.CharTo, SUBSTRING(i.word, n.N, 1)) -- do not alias
from #Inputs as i
cross apply #Numbers as n
left join #Lookups as l
on l.CharFrom = SUBSTRING(i.word, n.N, 1)
where n.N <= LEN(i.Word)
and i.Word = ix.Word
for xml path ('')
) as Substituted
from #Inputs as ix;
Ü ö ò ô å Ä Å É ï
. Pertanto, un metodo di traduzione / mappatura standard non funzionerà.
Ecco cosa ha funzionato se qualcuno in futuro lo desidera.
function accentHebrewToCleanHebrew($accentHebrew){
//Strip Extras
$search = array("֑", "֒", "֓", "֔", "֕",
"֖", "֗", "֘", "֙", "֚", "֛", "֜",
"֝", "֞", "֟", "֠", "֡", "֢", "֣",
"֤", "֥", "֦", "֧", "֨", "֩", "֪",
"֫", "֬", "֭", "֮", "֯", "ְ", "ֱ",
"ֲ", "ֳ", "ִ", "ֵ", "ֶ", "ַ", "ָ",
"ֹ", "ֺ", "ֻ", "ּ", "ֽ", "־", "ֿ",
"׀", "ׁ", "ׂ", "׃", "ׄ", "ׅ", "׆", "ׇ");
$replace = "";
$cleanHebrew = str_replace($search, $replace, $accentHebrew);
return $cleanHebrew;
}