Saya memerlukan Trik Pengkodean Char untuk Melucuti Tanda Aksen Bahasa Ibrani.
Contoh Sebelumnya
בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ
Contoh Setelah
בראשית ברא אלהים את השמים ואת הארץ
Saya memerlukan Trik Pengkodean Char untuk Melucuti Tanda Aksen Bahasa Ibrani.
Contoh Sebelumnya
בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ
Contoh Setelah
בראשית ברא אלהים את השמים ואת הארץ
Jawaban:
Kuncinya di sini adalah untuk menyadari bahwa karakter ini yang Anda lihat dalam pertanyaan dengan "aksen" tidak benar-benar yang karakter (yaitu "Ini bukandroidkarakter yang Anda cari ";-))." Aksen "adalah berbagai jenis notasi yang menunjukkan hal-hal seperti:
vokal (garis dan titik yang biasanya di bawah huruf):
pelafalan (titik-titik yang biasanya di dalam atau di atas huruf):
tanda baca
Huruf-huruf Ibrani yang sebenarnya adalah yang diperlihatkan dalam versi yang dipreteli (yaitu hasil akhir dari apa yang diminta di sini). Apa yang kita sebut di sini sebagai "aksen" dikenal sebagai tanda diakritik. Artikel Wikipedia tentang diakritik Ibrani memiliki banyak informasi bagus tentang tanda-tanda ini, termasuk gambar dan keterangan berikut:
Kej 1: 9 Dan Tuhan berkata, "Biarkan air dikumpulkan". Huruf hitam, menunjuk merah, cantillation berwarna biru
Mendapatkan dari karakter dasar tersebut ke apa yang ditampilkan baris pertama (dengan vokal, dll.) Adalah masalah menambahkan satu atau lebih "aksen". Unicode (UTF-16 dalam SQL Server, meskipun interpretasi default hanya menangani poin kode UCS-2 / Basic Multilingual Plane (BMP)) memungkinkan beberapa karakter untuk overlay karakter non-overlay lain ketika berdekatan dengan mereka. Ini dikenal sebagai Menggabungkan Karakter .
Berarti:
SELECT DATALENGTH(N'מַ֖'); -- character taken from original given text
Pengembalian:
6
tidak 2
seperti kebanyakan orang harapkan dari melihat karakter tunggal, byte ganda. Jadi mungkin kita mencoba mencari karakter apa yang ada di sana dengan melakukan:
SELECT UNICODE(N'מַ֖');
yang mengembalikan:
1502
Tentu saja, UNICODE
dan ASCII
fungsi hanya mengembalikan INT
nilai karakter pertama dari string apa pun yang diberikan kepada mereka. Tetapi nilai 1502 hanya mencakup 2 byte, yang membuat 4 byte tidak terhitung. Melihat nilai biner / hex dari "karakter" Ibrani yang sama:
SELECT NCHAR(1502), CONVERT(BINARY(2), UNICODE(N'מַ֖')), CONVERT(VARBINARY(10), N'מַ֖');
kita mendapatkan:
מ
0x05DE 0xDE05B7059605
Sekarang, 0x05DE adalah representasi hex dari 1502, dan 1502 hanyalah " מ ". Bagian selanjutnya dapat dipisahkan menjadi tiga set 2-byte: DE05 B705 9605 . Sekarang, nilai-nilai string Unicode disimpan di Little Endian, yang berarti urutan byte dibalik. Jika kita mengganti masing-masing dari tiga set yang kita dapatkan:
05DE (karakter dasar) 05B7 0596 (tidak dihitung untuk 4 byte).
Baik. Jadi apa yang terjadi jika kita menghapus karakter dasar itu?
SELECT REPLACE(N'מַ֖' COLLATE Hebrew_BIN2, NCHAR(1502) COLLATE Hebrew_BIN2, '');
Itu mengembalikan dua karakter yang tersisa (tidak mudah dilihat di sini jadi saya telah membuat baris berikut sebagai tajuk untuk meningkatkan ukuran font; Anda juga dapat menjalankan di atas REPLACE
untuk melihatnya):
Oleh karena itu, kita perlu menghapus setiap titik kode individu yang merupakan salah satu dari karakter kombinasi "ekstra" ini (ditemukan di: http://unicode-table.com/en/search/?q=hebrew ) dan itu akan meninggalkan kita dengan karakter dasar. Kita dapat melakukannya melalui:
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;
Dan kemudian kita bisa mengujinya dengan teks asli sebagai berikut:
DECLARE @Hebrew NVARCHAR(200) = N'בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ';
SELECT dbo.RemoveHebrewAccents(@Hebrew);
Pengembalian:
Catatan tambahan:
Secara teknis, ada satu set titik kode antara 64298 dan 64334 yang memiliki beberapa vokal dan "aksen" pelafalan yang tertanam dalam karakter. Jika itu perlu ditangani, itu bisa menjadi langkah kedua dalam fungsi untuk melakukan penggantian sederhana karakter-karakter tersebut.
Tampaknya aksen, tanda baca, dll ini hanya cocok dengan titik kode ketika menggunakan susunan biner. Bahkan menggunakan Hebrew_100_CS_AS_KS_WS_SC
tidak cocok dengan mereka. Tapi berikut melakukan pekerjaan: Hebrew_BIN
, Hebrew_BIN2
, Latin1_General_BIN
, dan Latin1_General_BIN2
. Dalam fungsi saya akhirnya menggunakan Hebrew_BIN2
. Harap perhatikan bahwa saat menggunakan koleksi biner, kecuali jika Anda memiliki kebutuhan khusus untuk menggunakan _BIN
koleksi yang lebih lama , Anda hanya boleh menggunakan _BIN2
koleksi yang lebih baru .
Bagi siapa pun yang penasaran, contoh teks Ibrani sebenarnya adalah Bereishis 1: 1 (itu juga kata pertama di sisi kanan karena bahasa Ibrani dibaca kanan-ke-kiri; dalam bahasa Inggris itu adalah "Kejadian 1: 1" itu bukan terjemahan langsung dari kata tersebut, hanya nama buku pertama Taurat / Alkitab; terjemahan langsungnya adalah "pada awalnya"):
Pada mulanya Allah menciptakan langit dan Bumi
2015-01-19: Saya menemukan beberapa sumber yang bagus yang menjelaskan kedua Combining Characters dan the Hebrew set:
Ini adalah masalah yang menarik, dan saya agak berhadapan dengan karakter Jepang. Saya menabrak sedikit dinding bata untuk menemukan karakter bermasalah Anda, meskipun saya harap ini membuat Anda pergi ke suatu tempat dengan menemukan mereka.
Pertama-tama saya memasukkan semua NCHAR ke dalam tabel:
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
Kemudian saya menemukan salah satu karakter non-aksen:
SELECT c.CharOrder, c.Result
FROM #CHARS AS c
WHERE c.Result = N'ר'
ORDER BY c.CharOrder
Kemudian saya menemukan rentang karakter karakter Ibrani:
SELECT c.CharOrder, c.Result
FROM #CHARS AS c
WHERE c.CharOrder >= 1488
AND c.CharOrder < 1523
ORDER BY c.CharOrder
Tetapi mencoba menemukan aksen yang Anda inginkan, mereka tampaknya tidak muncul, kecuali satu klik pada kode 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
Jadi hanya dengan melihat karakter di sekitarnya, saya tidak bisa mengidentifikasi kecocokan lain dengan teks Anda.
SELECT c.CharOrder, c.Result
FROM #CHARS AS c
WHERE c.CharOrder >= 8499
AND c.CharOrder < 8539
ORDER BY c.CharOrder
Banyak dari mereka tampaknya dilemparkan sebagai persegi kecil kecil yang samar-samar dari apa pun.
Sekali lagi, maaf itu bukan solusi, tetapi harap ini membantu.
Saya telah menggunakan tabel Angka. Ada sejumlah posting yang menjelaskan apa ini, mengapa ini berguna dan bagaimana mendapatkannya secara efisien.
Saya tidak menggunakan fungsionalitas bawaan untuk mengonversi karakter beraksen ke padanan non-beraksen. Alih-alih, saya membuat daftar pencarian yang akan Anda isi dengan konversi yang Anda butuhkan. Anda harus menggunakan nvarchar
dan mendefinisikan terjemahan Anda N'x'
, tentu saja.
Berkat posting ini untuk tip penggabungan baris.
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;
Ü ö ò ô å Ä Å É ï
. Karenanya, metode terjemahan / pemetaan standar tidak akan berfungsi.
Inilah yang berhasil jika ada orang di masa depan yang menginginkannya.
function accentHebrewToCleanHebrew($accentHebrew){
//Strip Extras
$search = array("֑", "֒", "֓", "֔", "֕",
"֖", "֗", "֘", "֙", "֚", "֛", "֜",
"֝", "֞", "֟", "֠", "֡", "֢", "֣",
"֤", "֥", "֦", "֧", "֨", "֩", "֪",
"֫", "֬", "֭", "֮", "֯", "ְ", "ֱ",
"ֲ", "ֳ", "ִ", "ֵ", "ֶ", "ַ", "ָ",
"ֹ", "ֺ", "ֻ", "ּ", "ֽ", "־", "ֿ",
"׀", "ׁ", "ׂ", "׃", "ׄ", "ׅ", "׆", "ׇ");
$replace = "";
$cleanHebrew = str_replace($search, $replace, $accentHebrew);
return $cleanHebrew;
}