J'ai besoin d'un tour d'encodage de caractères pour supprimer les marques d'accent hébreu.
Échantillon avant
בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ
Échantillon après
בראשית ברא אלהים את השמים ואת הארץ
la source
J'ai besoin d'un tour d'encodage de caractères pour supprimer les marques d'accent hébreu.
Échantillon avant
בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ
Échantillon après
בראשית ברא אלהים את השמים ואת הארץ
L'astuce ici est de réaliser que ces personnages que vous voyez dans la question avec les "accents" ne sont pas vraiment les personnages (c'est-à-dire "Ce ne sont pas lesdroïdescaractères que vous recherchez ";-)). Les" accents "sont différents types de notations indiquant des choses comme:
voyelles (lignes et points qui se trouvent généralement sous les lettres):
prononciation (points généralement à l'intérieur ou au-dessus des lettres):
ponctuation
Les lettres hébraïques réelles sont ce qui est montré dans la version dépouillée (c'est-à-dire le résultat final de ce qui est demandé ici). Ce que nous appelons ici "accents" sont connus comme des signes diacritiques. L'article de Wikipédia sur les signes diacritiques hébreux contient de nombreuses bonnes informations sur ces marques, notamment l'image et la légende suivantes:
Gen. 1: 9 Et Dieu dit: "Que les eaux soient recueillies". Lettres en noir, pointant en rouge, cantillation en bleu
Passer de ces caractères de base à ce que montre la première ligne (avec les voyelles, etc.) consiste à ajouter un ou plusieurs "accents". Unicode (UTF-16 dans SQL Server, bien que l'interprétation par défaut ne gère que les points de code UCS-2 / Basic Multilingual Plane (BMP)) permet à certains caractères de superposer un autre caractère non superposé lorsqu'ils sont adjacents à eux. Ceux-ci sont connus sous le nom de combinaison de caractères .
Sens:
SELECT DATALENGTH(N'מַ֖'); -- character taken from original given text
Retour:
6
pas 2
comme la plupart des gens s'attendraient à voir un caractère à deux octets. Alors peut-être que nous essayons de trouver quel personnage est là en faisant:
SELECT UNICODE(N'מַ֖');
qui renvoie:
1502
Bien sûr, les fonctions UNICODE
et ASCII
ne renvoient que la INT
valeur du premier caractère de la chaîne qui leur est donnée. Mais une valeur de 1502 ne couvre que 2 octets, ce qui laisse 4 octets non comptabilisés. En regardant les valeurs binaires / hexadécimales de ce même "caractère" hébreu:
SELECT NCHAR(1502), CONVERT(BINARY(2), UNICODE(N'מַ֖')), CONVERT(VARBINARY(10), N'מַ֖');
on a:
מ
0x05DE 0xDE05B7059605
Maintenant, 0x05DE est la représentation hexadécimale de 1502, et le 1502 n'est que le " מ ". La partie suivante peut être séparée en trois ensembles de 2 octets: DE05 B705 9605 . Maintenant, les valeurs de chaîne Unicode sont stockées dans Little Endian, ce qui signifie que l'ordre des octets est inversé. Si nous changeons chacun de ces trois ensembles, nous obtenons:
05DE (le caractère de base) 05B7 0596 (le non comptabilisé pour 4 octets).
D'accord. Alors, que se passe-t-il si nous supprimons ce caractère de base?
SELECT REPLACE(N'מַ֖' COLLATE Hebrew_BIN2, NCHAR(1502) COLLATE Hebrew_BIN2, '');
Cela renvoie les deux caractères restants (pas facile à voir ici, j'ai donc fait de la ligne suivante un en-tête afin d'augmenter la taille de la police; vous pouvez également exécuter ce qui précède REPLACE
pour les voir):
Par conséquent, nous devons supprimer chaque point de code individuel qui est l'un de ces caractères de combinaison "supplémentaires" (disponible sur: http://unicode-table.com/en/search/?q=hebrew ) et cela nous laissera avec les caractères de base. Nous pouvons le faire via:
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;
Et puis nous pouvons le tester avec le texte original comme suit:
DECLARE @Hebrew NVARCHAR(200) = N'בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ';
SELECT dbo.RemoveHebrewAccents(@Hebrew);
Retour:
Notes complémentaires:
Techniquement, il y a un ensemble de points de code entre 64298 et 64334 qui ont des voyelles et des "accents" de prononciation intégrés dans le caractère. Si ceux-ci doivent être traités, cela peut être une deuxième étape dans la fonction pour effectuer un simple remplacement de ces caractères.
Il semble que ces points de code d'accent, de ponctuation, etc. ne correspondent que lors de l'utilisation d'un classement binaire. Même l'utilisation Hebrew_100_CS_AS_KS_WS_SC
ne leur correspondait pas. Mais ce qui suit fait le travail: Hebrew_BIN
, Hebrew_BIN2
, Latin1_General_BIN
et Latin1_General_BIN2
. Dans la fonction, j'ai fini par utiliser Hebrew_BIN2
. Veuillez noter que lorsque vous utilisez des classements binaires, sauf si vous avez un besoin spécifique d'utiliser les _BIN
classements plus anciens , vous ne devez utiliser que les _BIN2
classements les plus récents .
Pour ceux qui sont curieux, l'exemple de texte hébreu est en fait Bereishis 1: 1 (c'est aussi le premier mot à droite car l'hébreu est lu de droite à gauche; en anglais, ce serait "Genèse 1: 1" cependant ce n'est pas une traduction directe du mot, juste le nom du premier livre de la Torah / Bible; la traduction directe est "au début"):
Au début de la création de Dieu des cieux et de la Terre
2015-01-19: J'ai trouvé d'excellentes ressources qui expliquent à la fois la combinaison de caractères et le jeu de caractères hébreux:
C'est un problème intéressant, et je l'ai rencontré il y a quelque temps en travaillant avec des caractères japonais. J'ai heurté un peu un mur de briques en essayant de localiser vos personnages problématiques, bien que j'espère que cela vous amènera quelque part à les trouver.
J'ai d'abord mis tous les NCHAR dans une table:
Ensuite, j'ai localisé l'un des caractères non accentués:
Ensuite, j'ai localisé la gamme de caractères dans lesquels se trouvent les caractères hébreux:
Mais en essayant de trouver les caractères accentués que vous voulez, ils ne semblent pas apparaître, sauf un hit au code 8501.
Donc, juste en regardant les personnages environnants, je ne peux pas vraiment identifier d'autres correspondances avec votre texte.
Beaucoup d'entre eux semblent être jetés comme ces petits rectangles nébuleux de quoi que ce soit.
Encore une fois, désolé, ce n'est pas une solution, mais j'espère que cela aide.
la source
J'ai utilisé une table Numbers. Il existe un certain nombre de messages expliquant ce que c'est, pourquoi c'est utile et comment en obtenir un efficacement.
Je n'utilise aucune fonctionnalité intégrée pour convertir des caractères accentués en équivalent non accentué. Au lieu de cela, je construis une liste de recherche que vous remplirez avec les conversions dont vous avez besoin. Vous devrez bien sûr utiliser
nvarchar
et définir vos traductionsN'x'
.Merci à ce post pour le conseil de concaténation de ligne.
la source
Ü ö ò ô å Ä Å É ï
. Par conséquent, une méthode de traduction / mappage standard ne fonctionnera pas.Voici ce qui a fonctionné si quelqu'un à l'avenir le souhaite.
function accentHebrewToCleanHebrew($accentHebrew){ //Strip Extras $search = array("֑", "֒", "֓", "֔", "֕", "֖", "֗", "֘", "֙", "֚", "֛", "֜", "֝", "֞", "֟", "֠", "֡", "֢", "֣", "֤", "֥", "֦", "֧", "֨", "֩", "֪", "֫", "֬", "֭", "֮", "֯", "ְ", "ֱ", "ֲ", "ֳ", "ִ", "ֵ", "ֶ", "ַ", "ָ", "ֹ", "ֺ", "ֻ", "ּ", "ֽ", "־", "ֿ", "׀", "ׁ", "ׂ", "׃", "ׄ", "ׅ", "׆", "ׇ"); $replace = ""; $cleanHebrew = str_replace($search, $replace, $accentHebrew); return $cleanHebrew; }
la source