Cara Melucuti Tanda Aksen Bahasa Ibrani

17

Saya memerlukan Trik Pengkodean Char untuk Melucuti Tanda Aksen Bahasa Ibrani.

Contoh Sebelumnya

בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ

Contoh Setelah

בראשית ברא אלהים את השמים ואת הארץ

Didekripsi
sumber

Jawaban:

26

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):

    huruf dasar "ה" = "h"; "הֶ" = "heh" dan "הָ" = "hah"

  • pelafalan (titik-titik yang biasanya di dalam atau di atas huruf):

    "בּ" = "b" vs "ב" = "v", atau "שׂ" = "s" vs "שׁ" = "sh"

  • tanda baca

  • cantillation (bagaimana seharusnya dinyanyikan)

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"
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 2seperti 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, UNICODEdan ASCIIfungsi hanya mengembalikan INTnilai 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 REPLACEuntuk melihatnya):

Menghapus מ dari מַ֖ menyisakan dua karakter di bagian bawah: ַ֖

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_SCtidak 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 _BINkoleksi yang lebih lama , Anda hanya boleh menggunakan _BIN2koleksi 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:

Solomon Rutzky
sumber
@ Terima kasih! (lagi :). Mari kita lihat berapa lama komentar Anda bertahan saat ini ;-D (catatan untuk "proses" pembersihan hantu kami: itu tidak dimaksudkan untuk memiliki implikasi kasar atau sinis, dan senyuman dengan halo ini membuktikan bahwa 😇 seperti halnya kucing yang tersenyum ini 😺)
Solomon Rutzky
1
dan sekali lagi saya belajar sesuatu yang tidak terduga dari jawaban Anda. Bagus!
Max Vernon
1
Wow! Jawaban linguistik yang bagus dilontarkan dengan deskripsi yang sangat baik tentang penanganan pengodean! Terima kasih, Solomon!
Mike Williamson
1

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.

Erik Darling
sumber
1
re: "mencoba menemukan aksen yang Anda inginkan, mereka tampaknya tidak muncul", itu karena mereka tidak ada ;-). Saya menjelaskan lebih rinci dalam jawaban saya, tetapi pada dasarnya itu adalah karakter dasar dengan satu atau dua karakter overlay yang mengambil posisi yang terlihat sama dengan karakter dasar.
Solomon Rutzky
3
Itu keren sekali. Saya tidak akan pernah berpikir bahwa tanda itu terpisah dari karakter. Terima kasih.
Erik Darling
1

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 nvarchardan 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;
Michael Green
sumber
Michael, bahasa Ibrani sebenarnya tidak berfungsi seperti itu. Ini bukan "karakter beraksen" benar-benar dengan cara yang sama bahwa ini adalah: Ü ö ò ô å Ä Å É ï. Karenanya, metode terjemahan / pemetaan standar tidak akan berfungsi.
Solomon Rutzky
0

Inilah yang berhasil jika ada orang di masa depan yang menginginkannya.

function accentHebrewToCleanHebrew($accentHebrew){ //Strip Extras $search = array("&#1425;", "&#1426;", "&#1427;", "&#1428;", "&#1429;", "&#1430;", "&#1431;", "&#1432;", "&#1433;", "&#1434;", "&#1435;", "&#1436;", "&#1437;", "&#1438;", "&#1439;", "&#1440;", "&#1441;", "&#1442;", "&#1443;", "&#1444;", "&#1445;", "&#1446;", "&#1447;", "&#1448;", "&#1449;", "&#1450;", "&#1451;", "&#1452;", "&#1453;", "&#1454;", "&#1455;", "&#1456;", "&#1457;", "&#1458;", "&#1459;", "&#1460;", "&#1461;", "&#1462;", "&#1463;", "&#1464;", "&#1465;", "&#1466;", "&#1467;", "&#1468;", "&#1469;", "&#1470;", "&#1471;", "&#1472;", "&#1473;", "&#1474;", "&#1475;", "&#1476;", "&#1477;", "&#1478;", "&#1479;"); $replace = ""; $cleanHebrew = str_replace($search, $replace, $accentHebrew); return $cleanHebrew; }

Didekripsi
sumber