web-dev-qa-db-ja.com

ヘブライ語のアクセント記号を取り除く方法

ヘブライ語のアクセント記号を取り除くには、Charエンコーディングトリックが必要です。

サンプル前

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

サンプル後

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

17
Decrypted

ここでの秘訣は、「アクセント」の付いた質問に表示されるこれらの文字は、実際にはtheの文字ではないことを理解することです(つまり、「これらは ドロイド探している文字」;-))「アクセント」は、次のようなことを示すさまざまなタイプの表記法です。

  • 母音(通常は文字の下にある線と点):

    ベース文字 "ה" = "h"; 「הֶ」=「へ」と「הָ」=「へ」

  • 発音(通常は文字の内側または上にあるドット):

    「בּ」=「b」対「ב」=「v」、または「שׂ」=「s」対「שׁ」=「sh」

  • 句読点

  • カンチレーション(歌う方法)

実際のヘブライ語の文字は、削除されたバージョンで表示されるものです(つまり、ここで要求されているものの最終結果)。ここで「アクセント」と呼ぶものは、発音区別符号と呼ばれます。 ヘブライ語付加記号 に関するWikipediaの記事には、次の画像とキャプションを含む、これらのマークに関する多くの優れた情報があります。

Gen. 1:9 And God said, "Let the waters be collected"
創世記1:9神は言われた、「水を集めさせなさい」。黒の文字、赤で指し、青でカンチレーション

それらのベースキャラクターから最初の行(母音など)が示す内容に到達するには、1つ以上の「アクセント」を追加するだけです。 Unicode(SQL ServerではUTF-16、ただしデフォルトの解釈ではUCS-2 /基本多言語面(BMP)コードポイントのみを処理します)により、一部の文字が隣接しているときに、別の非オーバーレイ文字をオーバーレイできます。これらは 結合文字 として知られています。

意味:

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

戻り値:

6

2ではありません。ほとんどの人は、シングル、ダブルバイトの文字が表示されることを期待しています。だから、多分私たちは次のようにして、そこにいるキャラクターを見つけようとします:

SELECT UNICODE(N'מַ֖');

これは次を返します:

1502

もちろん、UNICODE関数とASCII関数は、指定された文字列の最初の文字のINT値のみを返します。ただし、1502の値は2バイトしかカバーしないため、4バイトは考慮されません。同じヘブライ語の「文字」の2進数/ 16進数の値を見てみましょう。

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

我々が得る:

מ
0x05DE  0xDE05B7059605

ここで、0x05DEは1502の16進表記であり、1502は "מ "。次の部分は、3つの2バイトセットに分割できます:DE05B7059605。現在、Unicode文字列値はリトルエンディアンに格納されています。つまり、バイト順が逆になっています。これらの3つのセットをそれぞれ切り替えると、次のようになります。

05DE(ベース文字)05B70596(4バイトを考慮に入れていません)。

OK。では、そのベースキャラクターを削除するとどうなりますか?

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

これは残りの2つの文字を返します(ここではわかりにくいので、フォントサイズを増やすために次の行をヘッダーにしました。上記のREPLACEを実行して表示することもできます):

מからמを削除すると、下部に2つの文字が残ります:ַ֖

したがって、これらの「余分な」結合文字の1つである個々のコードポイントをそれぞれ取り除く必要があります(次の場所にあります 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の間には、some母音と発音の「アクセント」が組み込まれたコードポイントのセットがあります。それらを処理する必要がある場合、それはそれらの文字の単純な置換を行うための関数の2番目のステップになる可能性があります。

  • これらのアクセント、句読点などのコードポイントは、バイナリ照合を使用する場合にのみ一致するようです。 Hebrew_100_CS_AS_KS_WS_SCを使用しても一致しませんでした。ただし、次のように機能しました:Hebrew_BINHebrew_BIN2Latin1_General_BINLatin1_General_BIN2。関数では、Hebrew_BIN2を使用してしまいました。バイナリ照合順序を使用する場合、古い_BIN照合順序を使用する必要がない限り、新しい_BIN2照合順序のみを使用する必要があることに注意してください。

  • 好奇心が強い人にとっては、ヘブライ語のサンプルテキストは実際にはBereishis 1:1です(これは、ヘブライ語が右から左に読まれるので、右側の最初の単語でもあります。英語では「創世記1:1」ですがそれは御言葉を直接翻訳したものではなく、律法学者/聖書の最初の本の名前だけです;直接の翻訳は「初めに」です):

    神が天と地を創造する初めに

  • 2015-01-19:結合文字とヘブライ文字セットの両方を説明する素晴らしいリソースを見つけました:

26
Solomon Rutzky

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;
1
Michael Green

これは興味深い問題で、私はしばらく前に日本語の文字を扱っていたときに直面した問題の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

次に、アクセントのない文字の1つを見つけました。

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で1回ヒットする以外は表示されないようです。

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
Erik Darling

これは、将来誰かが望めばうまくいくものです。

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

0
Decrypted