Answers:
这里的技巧是要认识到您在问题中看到的带有“重音符号”的这些字符并不是真的 ”的这些字符的字符(即“这些不是机器人您要查找的字符“ ;-))。”重音符号“是各种类型的表示法,它们表示:
元音(通常在字母下方的线和点):
发音(通常在字母内部或上方的点):
标点
实际的希伯来字母是精简版本中显示的内容(即,此处要求的最终结果)。我们这里所说的“重音符号”被称为变音标记。Wikipedia上有关希伯来变音符号的文章提供了很多有关这些标记的信息,包括以下图像和标题:
创1:9上帝说:“让水被收集”。黑色字母,红色,蓝色代表
从这些基本字符到第一行(带有元音等)显示的内容是添加一个或多个“重音符号”的问题。Unicode(SQL Server中的UTF-16,尽管默认解释仅处理UCS-2 /基本多语言平面(BMP)代码点),使某些字符在相邻时可以覆盖另一个非覆盖字符。这些被称为组合字符。
含义:
SELECT DATALENGTH(N'מַ֖'); -- character taken from original given text
返回值:
6
不像2
大多数人期望的那样,看到一个双字节字符。因此,也许我们尝试通过执行以下操作找到其中的角色:
SELECT UNICODE(N'מַ֖');
返回:
1502
当然,UNICODE
and 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);
返回值:
补充说明:
从技术上讲,在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年1月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;
}