Мені потрібен трюк із шифруванням позначок для того, щоб позбутися знаків наголосі на івриті.
Зразок раніше
בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ
Зразок після
בראשית ברא אלהים את השמים ואת הארץ
Мені потрібен трюк із шифруванням позначок для того, щоб позбутися знаків наголосі на івриті.
Зразок раніше
בְּרֵאשִׁ֖ית בָּרָ֣א אֱלֹהִ֑ים אֵ֥ת הַשָּׁמַ֖יִם וְאֵ֥ת הָאָֽרֶץ
Зразок після
בראשית ברא אלהים את השמים ואת הארץ
Відповіді:
Хитрість тут полягає в тому, щоб зрозуміти, що ці символи, які ви бачите в питанні з "наголосами", насправді не є персонажами (тобто "Це недроїдисимволів, яких ви шукаєте ";-))." Акценти "- це різні типи позначень, що вказують на такі речі:
голосні (рядки та крапки, які зазвичай знаходяться під літерами):
вимова (крапки, які зазвичай знаходяться всередині або вище літер):
пунктуація
Фактичні івритські букви - це те, що показано у викресленій версії (тобто кінцевий результат того, що тут вимагається). Те, що ми тут маємо на увазі як «наголоси», називаються діакритичними знаками. Стаття у Вікіпедії про івритську діакритику є багато хорошої інформації про ці знаки, включаючи наступні зображення та підписи:
Буття 1: 9 І Бог сказав: Нехай збираються води! Букви чорного кольору, вказівні червоним кольором, контиляція синім кольором
Перехід від цих базових символів до того, що показує перший рядок (з голосними голосами тощо) - питання додавання одного або декількох "наголосів". 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 - лише " מ ". Наступну частину можна розділити на три двобайтові набори: 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);
Повернення:
Додаткові нотатки:
Технічно існує набір кодових точок між 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;
}