วิธีการตัดเครื่องหมายเน้นภาษาฮิบรู


17

ฉันต้องการเคล็ดลับการเข้ารหัส Char เพื่อเปลื้องเครื่องหมายสำเนียงภาษาฮิบรู

ตัวอย่างก่อน

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

ตัวอย่างหลังจาก

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

คำตอบ:


26

เคล็ดลับที่นี่คือการรู้ว่าตัวละครเหล่านี้ที่คุณเห็นในคำถามกับ "สำเนียง" ไม่ได้จริงๆตัวอักษร (คือ "เหล่านี้ไม่ได้หุ่นตัวอักษรที่คุณกำลังมองหา ";-))" การเน้นเสียง "เป็นสัญลักษณ์ประเภทต่าง ๆ ที่บ่งบอกถึงสิ่งต่าง ๆ เช่น:

  • สระ (เส้นและจุดที่อยู่ใต้ตัวอักษร):

    จดหมายฐาน "ה" = "h"; "הֶ" = "heh" และ "הָ" = "hah"

  • การออกเสียง (จุดที่มักจะอยู่ภายในหรือเหนือตัวอักษร):

    "בּ" = "b" vs "ב" = "v" หรือ "שׂ" = "s" vs "שׁ" = "sh"

  • วรรคตอน

  • cantillation (ควรร้องอย่างไร)

ตัวอักษรภาษาฮิบรูที่แท้จริงคือสิ่งที่แสดงในเวอร์ชั่นแบบถอดลง (เช่นผลลัพธ์สุดท้ายของสิ่งที่ต้องการที่นี่) สิ่งที่เราอ้างถึงในที่นี้คือ "เครื่องหมายเน้นเสียง" เรียกว่าเครื่องหมายกำกับเสียง บทความวิกิพีเดียเกี่ยวกับนักเขียนภาษาฮิบรูมีข้อมูลที่ดีมากมายเกี่ยวกับเครื่องหมายเหล่านี้รวมถึงรูปภาพและคำบรรยายต่อไปนี้:

Gen. 1: 9 และพระเจ้าตรัสว่า "ให้เก็บน้ำไว้"
Gen. 1: 9 และพระเจ้าตรัสว่า "ให้เก็บน้ำไว้" ตัวอักษรในสีดำชี้เป็นสีแดง cantillation ในสีน้ำเงิน

การได้รับจากตัวละครฐานเหล่านั้นไปยังสิ่งที่บรรทัดแรก (ด้วยเสียงสระ ฯลฯ ) แสดงให้เห็นว่าเป็นเรื่องของการเพิ่ม "สำเนียง" อย่างน้อยหนึ่งรายการ Unicode (UTF-16 ใน SQL Server แม้ว่าการตีความเริ่มต้นจะจัดการกับจุดโค้ด UCS-2 / Basic Multilingual Plane (BMP) เท่านั้น) ช่วยให้อักขระบางตัวซ้อนทับอักขระที่ไม่ใช่ภาพซ้อนทับอื่นเมื่ออยู่ติดกับพวกเขา เหล่านี้เรียกว่ารวมตัวละคร

ความหมาย:

SELECT DATALENGTH(N'מַ֖'); -- character taken from original given text

ผลตอบแทน:

6

ไม่ใช่2อย่างที่คนส่วนใหญ่คาดหวังจากการเห็นอักขระตัวเดียวไบต์คู่ ดังนั้นเราอาจลองค้นหาว่าตัวละครอยู่ที่นั่นด้วยการทำ:

SELECT UNICODE(N'מַ֖');

ซึ่งผลตอบแทน:

1502

แน่นอนว่าUNICODEและASCIIฟังก์ชั่นจะคืนINTค่าของอักขระตัวแรกของสตริงที่ระบุเท่านั้น แต่ค่าของ 1502 ครอบคลุม 2 ไบต์เท่านั้นซึ่งเหลือ 4 ไบต์ที่ไม่ต้องชำระ มองไปที่ค่าไบนารี / ฐานสิบหกของ "ตัวละคร" ฮีบรูเดียวกัน:

SELECT NCHAR(1502), CONVERT(BINARY(2), UNICODE(N'מַ֖')), CONVERT(VARBINARY(10), N'מַ֖');

เราได้รับ:

מ
0x05DE  0xDE05B7059605

ตอนนี้0x05DEคือการแสดงเลขฐานสิบหกของ 1502 และ 1502 เป็นเพียง " מ " ส่วนต่อไปสามารถแบ่งออกเป็นสามชุด 2 ไบต์: DE05 B705 9605 ตอนนี้ค่าสตริง Unicode จะถูกเก็บไว้ใน Little Endian ซึ่งหมายความว่าคำสั่งไบต์จะกลับรายการ หากเราสลับสามชุดเหล่านั้นเราจะได้รับ:

05DE (ตัวอักษรพื้นฐาน) 05B7 0596 (ที่ไม่ได้นับ 4 ไบต์)

ตกลง. แล้วจะเกิดอะไรขึ้นถ้าเราลบตัวละครฐานนั้น?

SELECT REPLACE(N'מַ֖' COLLATE Hebrew_BIN2, NCHAR(1502) COLLATE Hebrew_BIN2, '');

ที่ส่งคืนอักขระที่เหลืออยู่สองตัว (ไม่ใช่เรื่องง่ายที่จะดูที่นี่ดังนั้นฉันได้ทำบรรทัดต่อไปนี้เป็นส่วนหัวเพื่อเพิ่มขนาดตัวอักษรคุณสามารถเรียกใช้ด้านบนREPLACEเพื่อดูพวกเขา)

การลบמจากמַ֖เหลืออักขระสองตัวที่ด้านล่าง: ַ֖

ดังนั้นเราจำเป็นต้องตัดจุดรหัสแต่ละจุดออกซึ่งเป็นหนึ่งในอักขระรวม "พิเศษ" เหล่านี้ (พบได้ที่: http://unicode-table.com/en/search/?q=hebrew ) และนั่นจะทำให้เรา กับตัวละครฐาน เราสามารถทำได้ผ่าน:

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;

และจากนั้นเราสามารถทดสอบด้วยข้อความต้นฉบับดังนี้

DECLARE @Hebrew NVARCHAR(200) = N'בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ';

SELECT dbo.RemoveHebrewAccents(@Hebrew);

ผลตอบแทน:

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


หมายเหตุเพิ่มเติม:

  • ในทางเทคนิคมีชุดของรหัสจุดระหว่าง 64,298 และ 64,334 ว่าจะมีบางสระและการออกเสียง "สำเนียง" ที่สร้างขึ้นในตัวละคร หากจำเป็นต้องได้รับการจัดการนั่นอาจเป็นขั้นตอนที่สองในการทำงานเพื่อแทนที่อักขระเหล่านั้นได้อย่างง่ายดาย

  • ดูเหมือนว่าสำเนียงเครื่องหมายวรรคตอนและจุดโค้ดอื่น ๆ ตรงกันเฉพาะเมื่อใช้การเปรียบเทียบแบบไบนารี แม้ใช้Hebrew_100_CS_AS_KS_WS_SCไม่ตรงกับพวกเขา แต่ต่อไปนี้จะไม่ทำงาน: Hebrew_BIN, Hebrew_BIN2, และLatin1_General_BIN ในการทำงานของผมสิ้นสุดการใช้Latin1_General_BIN2 Hebrew_BIN2โปรดทราบว่าเมื่อใช้การเปรียบเทียบแบบไบนารีนอกจากว่าคุณจำเป็นต้องใช้การ_BINเปรียบเทียบแบบเก่าคุณควรใช้การ_BIN2จัดเรียงแบบใหม่เท่านั้น

  • สำหรับคนที่อยากรู้อยากเห็นข้อความตัวอย่างภาษาฮิบรูเป็นจริง Bereishis 1: 1 (นั่นเป็นคำแรกทางด้านขวาเมื่อภาษาฮิบรูอ่านจากขวาไปซ้าย; ในภาษาอังกฤษมันจะเป็น "ปฐมกาล 1: 1" นั่นไม่ใช่การแปลโดยตรงของคำเพียงแค่ชื่อของหนังสือเล่มแรกของโตราห์ / พระคัมภีร์; การแปลโดยตรงคือ "ในตอนแรก"):

    ในการเริ่มต้นของการสร้างสวรรค์และโลก

  • 2015-01-19:ฉันพบทรัพยากรที่ยอดเยี่ยมซึ่งอธิบายทั้งชุดอักขระผสมและชุดอักขระภาษาฮิบรู:


@ คินขอบคุณ! (อีกครั้ง :) ลองมาดูว่าระยะเวลาที่ความคิดเห็นของคุณมีชีวิตอยู่เวลานี้ ;-D (หมายเหตุผีของเราทำความสะอาด "ขั้นตอน" นั่นไม่ได้หมายความว่ามีหยาบหรือเยาะเย้ยความหมายและยิ้มนี้ที่มีรัศมีพิสูจน์😇ว่าไม่นี้แมวยิ้ม😺)
โซโลมอน Rutzky

1
และอีกครั้งฉันเรียนรู้สิ่งที่ไม่คาดคิดจากคำตอบ ดี!
Max Vernon

1
ว้าว! ภาษาศาสตร์ดีตอบโยนในที่มีความยอดเยี่ยมรายละเอียดของการจัดการการเข้ารหัส! ขอบคุณโซโลมอน!
Mike Williamson

1

นี่เป็นปัญหาที่น่าสนใจและฉันต้องเผชิญกับการทำงานกับตัวละครญี่ปุ่นมาระยะหนึ่งแล้ว ฉันทุบกำแพงอิฐเล็กน้อยเพื่อค้นหาตัวละครที่มีปัญหาของคุณ แต่ฉันหวังว่านี่จะทำให้คุณไปหาที่อื่นได้

ครั้งแรกฉันได้ NCHARs ทั้งหมดลงในตาราง:

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

จากนั้นฉันก็อยู่ที่หนึ่งในตัวอักษรที่ไม่เน้นเสียง:

SELECT  c.CharOrder, c.Result
FROM    #CHARS AS c
WHERE c.Result = N'ר'
ORDER BY c.CharOrder

จากนั้นฉันก็กำหนดช่วงของตัวอักษรที่ตัวอักษรภาษาฮิบรูอยู่:

SELECT  c.CharOrder, c.Result
FROM    #CHARS AS c
WHERE c.CharOrder >= 1488
AND c.CharOrder < 1523
ORDER BY c.CharOrder

แต่พยายามค้นหาตัวอักษรที่เน้นเสียงที่คุณต้องการพวกมันดูเหมือนจะไม่ปรากฏยกเว้นว่ามีการกดหนึ่งครั้งที่รหัส 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

ดังนั้นเมื่อมองไปที่ตัวละครโดยรอบฉันไม่สามารถระบุคู่อื่น ๆ ที่ตรงกับข้อความของคุณได้

SELECT  c.CharOrder, c.Result
FROM    #CHARS AS c
WHERE c.CharOrder >= 8499
AND c.CharOrder < 8539
ORDER BY c.CharOrder

หลายคนดูเหมือนจะถูกโยนเป็นสี่เหลี่ยมเล็ก ๆ ที่คลุมเครือของอะไรก็ตาม

ขออภัยอีกครั้งว่าไม่ใช่วิธีแก้ปัญหา แต่หวังว่าจะช่วยได้


1
Re: "พยายามค้นหาตัวอักษรที่เน้นเสียงที่คุณต้องการพวกเขาดูเหมือนจะไม่ปรากฏ" นั่นเป็นเพราะพวกเขาไม่มีตัวตน ;-) ฉันอธิบายรายละเอียดเพิ่มเติมในคำตอบของฉัน แต่โดยทั่วไปมันเป็นตัวละครฐานที่มีอักขระซ้อนทับหนึ่งหรือสองตัวที่ใช้ตำแหน่งที่มองเห็นได้เช่นเดียวกับตัวละครพื้นฐาน
โซโลมอน Rutzky

3
มันเจ๋งจริงๆ ฉันไม่เคยคิดเลยว่าเครื่องหมายเหล่านั้นจะแยกออกจากตัวละคร ขอบคุณ
Erik Darling

1

ฉันใช้ตารางตัวเลข มีจำนวนโพสต์ใด ๆ ที่อธิบายสิ่งนี้คือสาเหตุที่มีประโยชน์และวิธีการรับอย่างมีประสิทธิภาพ

ฉันไม่ใช้ฟังก์ชันในตัวใด ๆ เพื่อแปลงอักขระที่เน้นเสียงให้เทียบเท่าที่ไม่เน้นเสียง แต่ฉันสร้างรายการค้นหาที่คุณจะเติมด้วยการแปลงที่คุณต้องการ คุณจะต้องใช้nvarcharและกำหนดคำแปลของคุณเป็นN'x'แน่นอน

ขอบคุณโพสต์นี้สำหรับเคล็ดลับการต่อแถว

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;

ไมเคิลฮีบรูไม่ทำงานอย่างนั้นจริง ๆ เหล่านี้ไม่ได้ "ตัวละครสำเนียง" Ü ö ò ô å Ä Å É ïอย่างแท้จริงในทางเดียวกันว่าสิ่งเหล่านี้: ดังนั้นวิธีการแปล / การแมปมาตรฐานจะไม่ทำงาน
โซโลมอน Rutzky

0

นี่คือสิ่งที่ทำงานถ้าใครในอนาคตต้องการ

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; }

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.