Pino Carafa Ответов: 3

Как мне перевести этот очень простой синтаксис C# в VB?


Я пытаюсь решить проблему с "недопустимыми высокими суррогатными символами" в строке.

Один из примеров, которые я нашел в интернете, показывает, как создать такую строку в C#

string s = "a\ud800b";


Человек, создавший этот пример, утверждает, что
s.Normalize();
потерпеть неудачу.

И я в тупике. Независимо от того, что я пытаюсь сделать. VB.NET похоже, что результирующая строка всегда является хорошей, "нормализованной" строкой.

Как я могу воссоздать эту проблемную строку в VB.NET-что?

Что я уже пробовал:

Dim sFoo As String

Dim bytes() As Byte

bytes = {97, 216, 0, 98}
sFoo = System.Text.Encoding.Unicode.GetString(bytes)


и я попробовал поменять местами байты для \ud800

Dim sFoo As String

Dim bytes() As Byte

bytes = {97, 0, 216, 98}
sFoo = System.Text.Encoding.Unicode.GetString(bytes)


Я пробовал разные другие кодировки.... UTF7, utf8 в, кодировках utf32, BigEndianUnicode..... каждый раз, когда я пытаюсь проверить, является ли sFoo.IsNormalized он счастливо возвращает "True" и то .Вызов Normalize() всегда завершается успешно.....

3 Ответов

Рейтинг:
28

OriginalGriff

Dim s As String = "a" + ChrW(&HD800) + "b"
Dim t As String = s.Normalize()

Причина его неудачи заключается в том, что "D800" не является допустимым символом Юникода, они являются "суррогатами" и не могут быть "нормализованы": Часто задаваемые вопросы - UTF-8, UTF-16, UTF-32 & BOM[^]


Pino Carafa

Боже, как все просто, а? Большое-большое спасибо.

OriginalGriff

Всегда пожалуйста!

Рейтинг:
1

Pino Carafa

Решение OriginalGriff является идеальным решением этого вопроса. Я просто публикую здесь еще один "ответ", поскольку он позволяет мне отформатировать код, который я собираюсь опубликовать.

Мое первоначальное намерение состояло в том, чтобы иметь дело с такими строками, в основном находя способ удалить такой "мусор" из строки, не затрагивая строку слишком сильно.

Это вызывало проблему записи в XML. Следующим будет не:

Dim sFoo As String = "a" + ChrW(&HD800) + "b"

Dim oXML As System.Xml.XmlDocument
Dim oRoot As System.Xml.XmlElement

oXML = New System.Xml.XmlDocument
oRoot = oXML.CreateElement("foo")
oXML.AppendChild(oRoot)
oRoot.InnerText = sFoo
oXML.Save(System.IO.Path.Combine(System.IO.Path.GetTempPath, "foo.xml"))


Чтобы исправить это - или, по крайней мере, предотвратить ошибку -

Dim sFoo As String = "a" + ChrW(&HD800) + "b"

Try
    If Not sFoo.IsNormalized Then
        sFoo = sFoo.Normalize
    End If
Catch ex As Exception
    Dim bytes As Byte()
    bytes = System.Text.Encoding.Unicode.GetBytes(sFoo)
    sFoo = System.Text.Encoding.Unicode.GetString(bytes)
End Try

Dim oXML As System.Xml.XmlDocument
Dim oRoot As System.Xml.XmlElement

oXML = New System.Xml.XmlDocument
oRoot = oXML.CreateElement("foo")
oXML.AppendChild(oRoot)
oRoot.InnerText = sFoo
oXML.Save(System.IO.Path.Combine(System.IO.Path.GetTempPath, "foo.xml"))


Читателю: теперь это заменяет "мусор" другими символами, которые читатель-человек может воспринимать как "случайные" или бессмысленные. Для мой намерения и цели это совершенно нормально, но если вам нужно сделать что-то лучше, вам придется решать эту проблему самостоятельно :-)


Рейтинг:
1

Patrice T

Цитата:
Как мне перевести этот очень простой синтаксис C# в VB?

Не совсем решение, но в новостях :
https://ai.facebook.com/blog/deep-learning-to-translate-between-programming-languages[^]
Автоматический перевод по-прежнему является предметом исследований.
Таким образом, помимо самых простых переводов, автоматический перевод на самом деле не является решением проблемы.
Единственным эффективным решением является изучение обоих языков и перевод вручную.