Мне нужен трюк с кодировкой символов, чтобы убрать знаки ударения на иврите.
Образец перед
בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ
Образец после
בראשית ברא אלהים את השמים ואת הארץ
Мне нужен трюк с кодировкой символов, чтобы убрать знаки ударения на иврите.
Образец перед
בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ
Образец после
בראשית ברא אלהים את השמים ואת הארץ
Ответы:
Фокус в том , чтобы понять , что эти символы , которые вы видите в этом вопросе с «акцентом» не являются на самом деле эти символы (т.е. «Это недроидысимволы, которые вы ищете ";-))." Акценты "- это различные типы обозначений, обозначающих такие вещи, как:
гласные (строки и точки, которые обычно находятся под буквами):
произношение (точки, которые обычно находятся внутри или над буквами):
пунктуация
Фактические ивритские буквы - это то, что показано в урезанной версии (то есть конечный результат того, что запрашивается здесь). То, что мы называем здесь «акцентами», называется диакритическими знаками. В статье Википедии об ивритских диакритиках содержится много полезной информации об этих знаках, включая следующее изображение и подпись:
Быт. 1: 9 И сказал Бог: да соберется вода. Буквы черного цвета, указывающие красным, кантилляционные синим
Чтобы перейти от этих базовых символов к тому, что показано в первой строке (с гласными и т. Д.), Нужно добавить один или несколько «акцентов». Юникод (UTF-16 в SQL Server, хотя интерпретация по умолчанию обрабатывает только кодовые точки UCS-2 / Базовая многоязычная плоскость (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 - это только « מ ». Следующая часть может быть разделена на три двухбайтовых набора: DE05 B705 9605 . Теперь строковые значения Юникода хранятся в Little Endian, что означает обратный порядок байтов. Если мы переключим каждый из этих трех наборов, мы получим:
05DE (базовый символ) 05B7 0596 (неучтенный 4 байта).
Ok. Так что же произойдет, если мы удалим этот базовый символ?
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);
Возвращает:
Дополнительные замечания:
Технически, существует ряд кодовых точек между 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: я нашел несколько замечательных ресурсов, которые объясняют как комбинацию символов, так и набор символов иврита:
Это интересная проблема, с которой я столкнулся некоторое время назад, работая с японскими символами. Я наткнулся на кирпичную стену, пытаясь определить местонахождение ваших проблемных персонажей, хотя я надеюсь, что это поможет вам найти их.
Сначала я собрал все 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
Кажется, что многие из них выбрасываются в виде этих туманных маленьких прямоугольников.
Опять же, извините, это не решение, но надеюсь, что это поможет.
Я использовал таблицу чисел. Есть любое количество постов, объясняющих, что это такое, почему это полезно и как эффективно его получить.
Я не использую встроенную функциональность для преобразования символов без акцента в эквивалент без акцента. Вместо этого я создаю список поиска, который вы будете заполнять необходимыми конверсиями. Вы должны будете использовать 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;
Ü ö ò ô å Ä Å É ï
. Следовательно, стандартный метод перевода / отображения не будет работать.
Вот что сработало, если кто-то в будущем захочет.
function accentHebrewToCleanHebrew($accentHebrew){
//Strip Extras
$search = array("֑", "֒", "֓", "֔", "֕",
"֖", "֗", "֘", "֙", "֚", "֛", "֜",
"֝", "֞", "֟", "֠", "֡", "֢", "֣",
"֤", "֥", "֦", "֧", "֨", "֩", "֪",
"֫", "֬", "֭", "֮", "֯", "ְ", "ֱ",
"ֲ", "ֳ", "ִ", "ֵ", "ֶ", "ַ", "ָ",
"ֹ", "ֺ", "ֻ", "ּ", "ֽ", "־", "ֿ",
"׀", "ׁ", "ׂ", "׃", "ׄ", "ׅ", "׆", "ׇ");
$replace = "";
$cleanHebrew = str_replace($search, $replace, $accentHebrew);
return $cleanHebrew;
}