히브리어 악센트 표시를 제거하는 방법


17

히브리어 악센트 표시를 제거하려면 Char Encoding Trick이 필요합니다.

전에 샘플

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

샘플 후

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

답변:


26

여기서 요령은 "악센트"가있는 질문에서 볼 수있는 이러한 문자가 실제로 문자 가 아님을 인식 하는 것입니다 (예 : "이 문자는드로이드찾고있는 문자 ";-))."악센트 "는 다음과 같은 것을 나타내는 다양한 유형의 표기법입니다.

  • 모음 (일반적으로 글자 아래에있는 선과 점) :

    기본 문자 "ה"= "h"; "הֶ"= "heh"및 "הָ"= "hah"

  • 발음 (일반적으로 글자 안에 또는 글자 위에있는 점) :

    "בּ"= "b"vs "ב"= "v"또는 "שׂ"= "s"vs "שׁ"= "sh"

  • 구두

  • 캔틸 레이션 (노래하는 방법)

실제 히브리어 문자는 제거 된 버전에 표시되는 것입니다 (예 : 요청 된 결과의 최종 결과). 여기서 "악센트"라고하는 것을 분음 부호라고합니다. 히브리 분음 부호 에 대한 Wikipedia 기사 에는 다음 이미지와 캡션을 포함하여 이러한 마크에 대한 많은 좋은 정보가 있습니다.

창 1 : 9 하나님께서는 "물을 모으 라"고 말씀하셨습니다
창 1 : 9 하나님께서는 "물을 모으 라"고 말씀하셨습니다. 빨간색으로 가리키는 검은 색의 글자, 파란색으로 표시된 캔틸 레이션

이러한 기본 문자에서 첫 줄 (모음 등)이 표시하는 것은 하나 이상의 "악센트"를 추가하는 것입니다. 유니 코드 (SQL Server의 UTFF-16, 기본 해석은 UCS-2 / BMP (Basic Multilingual Plane) 코드 포인트 만 처리 함)를 사용하면 일부 문자가 다른 비 오버레이 문자와 인접 해있을 때 오버레이 할 수 있습니다. 이것을 문자 결합 이라고 합니다.

의미:

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

보고:

6

2대부분의 사람들이 단일 2 바이트 문자를 기대 하지는 않습니다 . 그래서 우리는 다음을 수행하여 어떤 캐릭터가 있는지 찾아보십시오.

SELECT UNICODE(N'מַ֖');

다음을 반환합니다.

1502

물론 UNICODEand ASCII함수 INT는 주어진 문자열의 첫 번째 문자 값만 반환합니다 . 그러나 값 1502는 2 바이트 만 포함하므로 4 바이트는 고려되지 않습니다. 동일한 히브리어 "문자"의 이진 / 16 진 값을 살펴보면 다음과 같습니다.

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

우리는 얻는다 :

מ
0x05DE  0xDE05B7059605

이제 0x05DE는 1502의 진수 표현이며, 1502 만 "입니다 מ ". 다음 부분은 3 개의 2 바이트 세트로 분리 될 수 있습니다 : DE05 B705 9605 . 이제 유니 코드 문자열 값이 Little Endian에 저장되므로 바이트 순서가 반대로됩니다. 이 세 세트 각각을 전환하면 다음과 같은 결과를 얻습니다.

05DE (기본 문자) 05B7 0596 (계산되지 않은 4 바이트).

확인. 기본 캐릭터를 제거하면 어떻게됩니까?

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

그러면 나머지 두 문자가 반환됩니다 (여기서 쉽게 볼 수 없으므로 글꼴 크기를 늘리기 위해 다음 줄을 헤더로 만들었습니다. 위 REPLACE를 실행하여 볼 수도 있습니다).

מ에서 Removing를 제거하면 맨 아래에 두 문자가 남습니다.

따라서, 우리는 이러한 "추가"조합 문자 ( 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);

보고:

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


추가 사항 :

  • 기술적으로해야합니까 64298과 64334 사이의 코드 포인트의 집합이 일부 모음과 캐릭터에 내장 된 발음 "악센트". 그것들을 처리 해야하는 경우, 문자의 간단한 교체를 수행하는 기능의 두 번째 단계가 될 수 있습니다.

  • 이 악센트, 문장 부호 등의 코드 포인트는 이진 데이터 정렬을 사용할 때만 일치하는 것으로 보입니다. 사용조차도 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 : 결합 문자와 히브리 문자 세트를 모두 설명하는 훌륭한 자료를 찾았습니다.


@Kin 감사합니다! (다시 :). -D (고스트 정리 "프로세스"에 대한 참고 : 무례하거나 조잡한 의미를 갖지 않았으며, 후광이있는 스마일은이 웃는 고양이와 마찬가지로 😇을 나타냅니다)
Solomon Rutzky

1
그리고 다시 당신의 대답에서 예기치 않은 것을 배웁니다. 좋은!
Max Vernon

1
와! 인코딩 처리에 대한 훌륭한 설명 과 함께 멋진 언어학 답변 ! 고마워, 솔로몬!
Mike Williamson

1

이것은 흥미로운 문제이며, 일본어 문자로 작업하면서 잠시 동안 직면 한 문제입니다. 나는 문제의 캐릭터를 찾으려고 약간의 벽돌 벽을 쳤지 만, 이것이 당신이 그들을 찾는 어딘가로 가길 바랍니다.

먼저 모든 NCHAR을 테이블에 넣었습니다.

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
다시 : "당신이 원하는 악센트 문자를 찾으려고 시도, 그들은 나타나지 않는 것"은 존재하지 않기 때문이다 ;-). 내 답변에 더 자세히 설명하지만 기본적으로 기본 문자와 동일한 가시 위치를 차지하는 하나 또는 두 개의 오버레이 문자가있는 기본 문자입니다.
Solomon Rutzky

3
정말 멋지다. 나는 그 마크가 캐릭터와 분리되어 있다고 생각하지 않았을 것입니다. 감사.
Erik Darling

1

Numbers 테이블을 사용했습니다. 이것이 무엇인지, 왜 유용한 지, 효율적으로 얻는 방법을 설명하는 게시물이 많이 있습니다.

내장 된 기능을 사용하여 악센트 문자를 비 액센트 문자로 변환하지 않습니다. 대신 필요한 전환으로 채울 조회 목록을 작성합니다. 물론 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;

마이클, 히브리어는 실제로 그런 식으로 작동하지 않습니다. 이것들은 다음과 같은 방식으로 진정한 "악센트 문자"가 아닙니다 Ü ö ò ô å Ä Å É ï. 따라서 표준 번역 / 매핑 방법이 작동하지 않습니다.
Solomon 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.