Есть ли в vb.net функция, которая скажет нам, эквивалентна ли 2 строка в UTF8 юникодном сопоставлении?
Этот вопрос похож на Как эмулировать сопоставление utf8_general_ci MySQLs при сравнении строк PHP, но я хочу использовать функцию для vb.net, а не для PhP.
В последнее время я делаю много якобы уникальных ключей.
Некоторые ключи в UTF8-юникодном сопоставлении эквивалентны.
Например, посмотрите на эти 2 ключа:
Байерс-стрит-бистро __38.15_-79.07 Байерс-стрит-бистро __38.15_-79.07
Если я вставлю это на первую страницу и посмотрю на исходный код, вы увидите
Байерс-улица-bistro__38.15_-79,07
Байерс-улица-бистро __38.15_-79,07
Примечание: при переполнении стека они все равно выглядят по-разному.
Я знаю, что это не то же самое. Я думаю, что даже при обмене стека это не показывает. Скажем, у меня есть 1 миллион таких записей, и я хочу проверить, будет ли 2 строка будет объявлена одинаковой при сопоставлении MySQL UTF8. Я хочу знать это перед загрузкой. Как я это сделал.
Так что vb.net считают, что это разные ключи. Когда мы создали запрос MySQL и загрузили его в базу данных, база данных пожаловалась, что это тот же ключ. Только одна жалоба и загрузка 1 миллиона баз данных застрянет.
Мы даже не знаем, что за чертовщина? В любом случае, где мы можем это найти?
Во всяком случае, я хочу функцию, которая, когда дано 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 ответа
Вероятно, использование разных кодовых точек Unicode для символов, которые выглядят одинаково, например, дефис-минус (- U+002D), en-dash (- U+2013) и em-dash (- U+2014) - три разных символа, которые выглядят одинаково аналогичный: - - -
Используйте функцию AscW() для проверки каждого символа.
РЕДАКТИРОВАТЬ:
Как указано в комментариях ниже, используйте пространство имен System.Text.NormalizationForm, чтобы определить, какие кодовые точки Unicode считаются эквивалентными символами.
Я использовал код VBA ниже, чтобы исследовать странные строки.
Я скопировал строку "byers-street" в ячейку D18 листа Excel и набрал 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