在vb.net中是否有一个函数可以告诉我们在UTF8 unicode整理下2字符串是否相同?

时间:2012-05-23 04:07:23

标签: vb.net utf-8 collation

这个问题与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

2 个答案:

答案 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书籍200ELeft-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