这个问题与How to emulate MySQLs utf8_general_ci collation in PHP string comparisons类似,但我想要的功能是vb.net而不是PhP。
最近我制作了许多据称独特的钥匙。
在UTF8 unicode排序规则下,某些键是等效的。
例如,看看这两个键:
Byers的路边-bistro__38.15_-79.07 Byers的-街道小酒馆__38.15_-79.07
如果我将其粘贴到首页,并查看您将看到的源代码
Byers的路边-bistro__38.15_-79.07
Byers的-街道小酒馆__38.15_-79.07
注意:在堆栈溢出时,它们看起来仍然不同。
我知道它不一样。我想即使在堆栈交换它也没有显示。假设我有100万条这样的记录,我想测试MySQL UTF8整理是否将2字符串声明为相同。我想在上传前知道。我该怎么做。
所以vb.net认为那些是不同的键。当我们创建mysql查询并将其上传到数据库时,数据库会抱怨它是相同的密钥。只有一个抱怨和100万个数据库的上传将被卡住。
我们甚至不知道到底是什么?无论如何,我们在哪里可以看到它?
无论如何,我想要一个函数,当给出2个字符串时,它会告诉我它们是否会被计算为相同或不相同。
如果可能,我们需要一个将字符串转换为最“标准”形式的函数。
例如,似乎没有任何编码,函数会重新确定所有那些字符并消除它。
有这样的事吗?
到目前为止,这就是我的工作。我需要更全面的东西。
Private Function StraightenQuotesReplacement() As Generic.Dictionary(Of String, String)
Static replacement As Generic.Dictionary(Of String, String)
If replacement Is Nothing Then
replacement = New Generic.Dictionary(Of String, String)
replacement.Add(ChrW(&H201C), """")
replacement.Add(ChrW(&H201D), """")
replacement.Add(ChrW(&H2018), "'")
replacement.Add(ChrW(&H2019), "'")
End If
Return replacement
End Function
<Extension()>
Public Function straightenQuotes(ByVal somestring As String) As String
For Each key In StraightenQuotesReplacement.Keys
somestring = somestring.Replace(key, StraightenQuotesReplacement.Item(key))
Next
Return somestring
End Function
<Extension()>
Public Function germanCharacter(ByVal s As String) As String
Dim t = s
t = t.Replace("ä", "ae")
t = t.Replace("ö", "oe")
t = t.Replace("ü", "ue")
t = t.Replace("Ä", "Ae")
t = t.Replace("Ö", "Oe")
t = t.Replace("Ü", "Ue")
t = t.Replace("ß", "ss")
Return t
End Function
<Extension()>
Public Function japaneseCharacter(ByVal s As String) As String
Dim t = s
t = t.Replace("ヶ", "ケ")
Return t
End Function
<Extension()>
Public Function greekCharacter(ByVal s As String) As String
Dim t = s
t = t.Replace("ς", "σ")
t = t.Replace("ι", "ί")
Return t
End Function
<Extension()>
Public Function franceCharacter(ByVal s As String) As String
Dim t = s
t = t.Replace("œ", "oe")
Return t
End Function
<Extension()>
Public Function RemoveDiacritics(ByVal s As String) As String
Dim normalizedString As String
Dim stringBuilder As New StringBuilder
normalizedString = s.Normalize(NormalizationForm.FormD)
Dim i As Integer
Dim c As Char
For i = 0 To normalizedString.Length - 1
c = normalizedString(i)
If CharUnicodeInfo.GetUnicodeCategory(c) <> UnicodeCategory.NonSpacingMark Then
stringBuilder.Append(c)
End If
Next
Return stringBuilder.ToString()
End Function
<Extension()>
Public Function badcharacters(ByVal s As String) As String
Dim t = s
t = t.Replace(ChrW(8206), "")
Return t
End Function
<Extension()>
Public Function sanitizeUTF8_Unicode(ByVal str As String) As String
Return str.ToLower.removeDoubleSpaces.SpacetoDash.EncodeUrlLimited.straightenQuotes.RemoveDiacritics.greekCharacter.germanCharacter
End Function
答案 0 :(得分:1)
可能对看起来相似的字符使用不同的unicode代码点,例如:连字符( - U + 002D),短划线( - U + 2013)和em-dash( - U + 2014)是三个看起来相似的不同字符: - - -
使用AscW()函数检查每个字符。
编辑:
如下面的注释所述,使用System.Text.NormalizationForm命名空间来确定哪些Unicode代码点被视为等效字符。
答案 1 :(得分:0)
我使用下面的VBA代码来调查奇怪的字符串。
我将“byers-street”行复制到Excel工作表的单元格D18,并在“立即”窗口中键入call DsplInHex(Range("D18"))
。结果是:
62 79 65 72 73 2D 73 74 72 65 65 74 2D 62 69 73 74 72 6F 5F 33 38 2E 31 35 2D 37 39 2E 30 37 20 62 79 65 72 73 2D 73 74 72 65 65 74 2D 62 69 73 74 72 6F 200E 5F 33 38 2E 31 35 2D 37 39 2E 30 37
添加换行符和一些空格给出:
62 79 65 72 73 2D 73 74 72 65 65 74 2D 62 69 73 74 72 6F 5F 33 38 2E 31 35 2D 37 39 2E 30 37 20
62 79 65 72 73 2D 73 74 72 65 65 74 2D 62 69 73 74 72 6F 200E 5F 33 38 2E 31 35 2D 37 39 2E 30 37
根据我的Unicode书籍200E
是Left-To-Right Mark
。我很想知道你是如何设法将这个角色添加到你的密钥中的。
VB.NET是正确的;这些键是不同的。 MySQL删除这些字符或您的传输过程删除它。无论哪种方式,您都需要检查源数据是否有趣。
Option Explicit
Public Sub DsplInHex(Stg As String)
Dim Pos As Long
For Pos = 1 To Len(Stg)
Debug.Print Hex(AscW(Mid(Stg, Pos, 1))) & " ";
Next
Debug.Print
End Sub