Yanıtlar:
Buradaki hile, "aksanlarla" soruda gördüğünüz karakterlerin gerçekte olmadığını anlamaktır. Bunlar değil" yani karakterler (Droidlerin"aksan" gibi şeyleri gösteren çeşitli gösterimler şunlardır:
ünlüler (genellikle harflerin altındaki çizgiler ve noktalar):
telaffuz (genellikle harflerin içinde veya üstünde olan noktalar):
noktalama
Gerçek İbranice harfler, soyulmuş versiyonda gösterilenlerdir (yani burada talep edilenlerin sonucu). Burada "aksan" olarak adlandırdığımız şey aksan işaretleri olarak bilinir. İbranice aksanlarla ilgili Wikipedia makalesinde, bu görüntü hakkında aşağıdaki görüntü ve resim yazısı da dahil olmak üzere birçok iyi bilgi bulunmaktadır:
Yaratılış 1: 9 Ve Tanrı dedi ki, "Bırak sular toplansın". Siyah harflerle, kırmızı, mavi renkle işaret
Bu temel karakterlerden ilk satırın (sesli harflerle vb.) Gösterdiği şeye ulaşmak, bir veya daha fazla "aksan" ekleme meselesidir. Unicode (SQL Server'da UTF-16, ancak varsayılan yorumlama yalnızca UCS-2 / Temel Çok Dilli Düzlem (BMP) kod noktalarını işler), bazı karakterlerin bitişik olduğunda başka bir yer paylaşımlı olmayan karakteri kaplamasına izin verir. Bunlar Karakterleri Birleştirme olarak bilinir .
Anlamı:
SELECT DATALENGTH(N'מַ֖'); -- character taken from original given text
İadeler:
6
2
çoğu insanın tek, çift baytlık bir karakter görmesini beklediği gibi değil . Belki de orada hangi karakterin olduğunu bulmaya çalışıyoruz:
SELECT UNICODE(N'מַ֖');
döndüren:
1502
Tabii ki, UNICODE
ve ASCII
işlevleri sadece INT
verildikleri dizenin ilk karakterinin değerini döndürür . Ancak 1502 değeri yalnızca 2 baytı kapsar, bu da 4 baytı hesaba katmaz. Aynı İbranice "karakterinin" ikili / onaltılı değerlerine bakıldığında:
SELECT NCHAR(1502), CONVERT(BINARY(2), UNICODE(N'מַ֖')), CONVERT(VARBINARY(10), N'מַ֖');
elde ederiz:
מ
0x05DE 0xDE05B7059605
Şimdi, 0x05DE , 1502'nin onaltılı gösterimidir ve 1502 yalnızca " מ " dir. Bir sonraki kısım üç 2 baytlık setlere ayrılabilir : DE05 B705 9605 . Şimdi, Unicode dize değerleri Little Endian'da saklanır, yani bayt sırası ters çevrilir. Bu üç setin her birini değiştirirsek:
05DE (temel karakter) 05B7 0596 (4 bayt için hesaplanmamış).
Tamam. Peki bu temel karakteri kaldırırsak ne olur?
SELECT REPLACE(N'מַ֖' COLLATE Hebrew_BIN2, NCHAR(1502) COLLATE Hebrew_BIN2, '');
Bu kalan iki karakteri döndürür (burada görmek kolay değil, bu yüzden yazı tipi boyutunu artırmak için aşağıdaki satırı bir başlık yaptım; ayrıca REPLACE
onları görmek için yukarıdan da çalıştırabilirsiniz ):
Bu nedenle, bu "ekstra" birleştirici karakterlerden ( http://unicode-table.com/en/search/?q=hebrew ) bulunan ve bizi terk edecek her bir kod noktasını çıkarmamız gerekir. temel karakterlerle. Bunu şu şekilde yapabiliriz:
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;
Ve sonra orijinal metinle aşağıdaki gibi test edebiliriz:
DECLARE @Hebrew NVARCHAR(200) = N'בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ';
SELECT dbo.RemoveHebrewAccents(@Hebrew);
İadeler:
Ek Notlar:
Teknik olarak, 64298 ile 64334 arasında bazı sesli harfleri ve telaffuz "aksanları" olan bir dizi kod noktası vardır . Bunların ele alınması gerekiyorsa, bu karakterlerin basit bir şekilde değiştirilmesi için işlevde ikinci bir adım olabilir.
Bu aksan, noktalama işaretleri vb. Kod noktalarının yalnızca ikili bir harmanlama kullanılırken eşleştiği görülmektedir. Kullanmak bile Hebrew_100_CS_AS_KS_WS_SC
onlara uymadı. Ama şu çalışma yaptı: Hebrew_BIN
, Hebrew_BIN2
, Latin1_General_BIN
, ve Latin1_General_BIN2
. Fonksiyonu kullanarak sona erdi Hebrew_BIN2
. İkili harmanlama kullanırken, eski _BIN
harmanlamaları kullanmak için özel bir gereksiniminiz yoksa, yalnızca yeni _BIN2
harmanlamaları kullanmanız gerektiğini lütfen unutmayın .
Merak eden herkes için, İbranice örnek metni aslında Bereishis 1: 1'dir (İbranice sağdan sola okunurken sağ taraftaki ilk sözcüktür; İngilizce'de "Genesis 1: 1" olurdu. bu kelimenin doğrudan çevirisi değil, sadece Tevrat / İncil'in ilk kitabının adıdır; doğrudan çeviri "başlangıçta"):
Tanrı'nın gökleri ve yeri yaratmasının başlangıcında
2015-01-19: Hem Kombinasyon Karakterlerini hem de İbranice karakter setini açıklayan bazı harika kaynaklar buldum:
Bu ilginç bir problem ve bir süredir Japonca karakterlerle çalışırken karşılaştım. Sorunlu karakterlerinizi bulmaya çalışan bir tuğla duvara çarptım, umarım bu sizi bulmak için bir yere götürür.
Önce tüm NCHAR'ları bir masaya aldım:
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
Sonra aksanlı olmayan karakterlerden birini buldum:
SELECT c.CharOrder, c.Result
FROM #CHARS AS c
WHERE c.Result = N'ר'
ORDER BY c.CharOrder
Sonra İbranice karakterlerin içinde bulunduğu karakter aralığını buldum:
SELECT c.CharOrder, c.Result
FROM #CHARS AS c
WHERE c.CharOrder >= 1488
AND c.CharOrder < 1523
ORDER BY c.CharOrder
Ama istediğiniz aksanlı karakterleri bulmaya çalışırken, 8501 kodunda bir isabet dışında görünmüyorlar.
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
Sadece çevredeki karakterlere baktığımda, metninizle başka bir eşleşme tanımlayamıyorum.
SELECT c.CharOrder, c.Result
FROM #CHARS AS c
WHERE c.CharOrder >= 8499
AND c.CharOrder < 8539
ORDER BY c.CharOrder
Birçoğu, her neyse o belirsiz küçük dikdörtgenler olarak atılmış gibi görünüyor.
Yine, üzgünüm bu bir çözüm değil, ama umarım yardımcı olur.
Sayılar tablosu kullandım. Bunun ne olduğunu, neden yararlı olduğunu ve nasıl verimli bir şekilde alınabileceğini açıklayan çok sayıda gönderi var.
Aksanlı karakterleri aksanlı olmayan eşdeğerine dönüştürmek için yerleşik işlevler kullanmıyorum. Bunun yerine, ihtiyacınız olan dönüşümlerle dolduracağınız bir arama listesi oluşturuyorum. Elbette nvarchar
çevirilerinizi kullanmalı ve tanımlamalısınız N'x'
.
Sayesinde bu yazı satır birleştirme ipucu için.
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;
Ü ö ò ô å Ä Å É ï
. Bu nedenle, standart bir çeviri / haritalama yöntemi çalışmaz.
Gelecekte birileri isterse işte ne işe yaradı.
function accentHebrewToCleanHebrew($accentHebrew){
//Strip Extras
$search = array("֑", "֒", "֓", "֔", "֕",
"֖", "֗", "֘", "֙", "֚", "֛", "֜",
"֝", "֞", "֟", "֠", "֡", "֢", "֣",
"֤", "֥", "֦", "֧", "֨", "֩", "֪",
"֫", "֬", "֭", "֮", "֯", "ְ", "ֱ",
"ֲ", "ֳ", "ִ", "ֵ", "ֶ", "ַ", "ָ",
"ֹ", "ֺ", "ֻ", "ּ", "ֽ", "־", "ֿ",
"׀", "ׁ", "ׂ", "׃", "ׄ", "ׅ", "׆", "ׇ");
$replace = "";
$cleanHebrew = str_replace($search, $replace, $accentHebrew);
return $cleanHebrew;
}