Перевод в транслит: как пропускать латинские символы?

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

Admiralisimys
Постоялец
Постоялец
 
Сообщения: 318
Зарегистрирован: 01.06.2009 (Пн) 10:26

Перевод в транслит: как пропускать латинские символы?

Сообщение Admiralisimys » 18.08.2009 (Вт) 13:04

Доброго времени суток!
Вслед за аналогичными темами в VB6 (Транслитерация) и VBA (Транслит) хотелось бы уточнить пару моментов по данной теме применительно к VB.NET
Вот собственно текущая реализация
Код: Выделить всё
Imports System

Class Translit
    Shared Sub Main(ByVal CmdArgs() As String)
        Dim Cyrillic_alphabet() As Char = {"А", "Б", "В", "Г", "Д", "Е", "Ё", "Ж", "З", "И", "Й", "К", "Л", "М", "Н", "О", "П", "Р", "С", "Т", "У", "Ф", "Х", "Ц", "Ч", "Ш", "Щ", "Ъ", "Ы", "Ь", "Э", "Ю", "Я"}
        Dim Translit() As String = {"A", "B", "V", "G", "D", "E", "E", "Zh", "Z", "I", "Y", "K", "L", "M", "N", "O", "P", "R", "S", "T", "U", "F", "H", "Ts", "Ch", "Sh", "Sch", "'", "Y", "'", "E", "Yu", "Ya"}
        'Dim a As String = vbNullString
        'For Each st As String In CmdArgs
        '    a = a & st & " "
        'Next
        Dim a As String = Console.ReadLine
        For Each ch As Char In a
            If Char.IsLetter(ch) Then
                For i As Byte = 0 To Cyrillic_alphabet.Length - 1
                    If (ch = Cyrillic_alphabet(i)) Or (ch = Char.ToLower(Cyrillic_alphabet(i))) Then
                        If Char.IsLower(ch) Then
                            Console.Write(Char.ToLower(Translit(i)))
                        Else
                            Console.Write(Translit(i))
                        End If
                    End If
                Next
            Else
                Console.Write(ch)
            End If
        Next
        Console.Read()
    End Sub
End Class
'*Cyrillic_alphabet - не полон, представлен только современным русским алфавитом

Сначала отделяю символы от знаков и цифр, далее сверка с алфавитом и вывод символа в нужном регистре. Вопрос, как отличать латинские символы, перевод которых не требуется, их просто нужно напечатать? Не вводить ещё и латинский алфавит?
Будь-то С и соответственная кодовая страница, всё решилось бы по кодам символов
Код: Выделить всё
//Latin
//for (int i=65;i<91;i++)
//for (int i=97;i<123;i++)
   
   //Cyrillic
//for (int i=128;i<160;i++)
//for (int i=160;i<175;i++)
//for (int i=224;i<240(255);i++)

А как в VB.NET подловить код Unicode символа? Да и вообще как протабулировать Unicode символы? На C коды (ASCII, но не Юникода) это можно сделать так
Код: Выделить всё
for (int i=0;i<255;i++)
   printf("%i %c\n",i,i);

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Re: Перевод в транслит: как пропускать латинские символы?

Сообщение Nord777 » 18.08.2009 (Вт) 13:24

Use
Dictionary(Of Char, String)
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5

Admiralisimys
Постоялец
Постоялец
 
Сообщения: 318
Зарегистрирован: 01.06.2009 (Пн) 10:26

Re: Перевод в транслит: как пропускать латинские символы?

Сообщение Admiralisimys » 25.08.2009 (Вт) 9:28

Nord777 спасибо. :)
Вот что получилось
Код: Выделить всё
Imports System
Imports System.Collections.Generic
Class Translit
    Shared Sub Main(ByVal CmdArgs() As String)
        Dim Cyrillic2Translit As New Dictionary(Of Char, String)
        With Cyrillic2Translit
            .Add("А", "A")
            .Add("Б", "B")
            .Add("В", "V")
            .Add("Г", "G")
            .Add("Д", "D")
            .Add("Е", "E")
            .Add("Ё", "E")
            .Add("Ж", "Zh")
            .Add("З", "Z")
            .Add("И", "I")
            .Add("Й", "Y")
            .Add("К", "K")
            .Add("Л", "L")
            .Add("М", "M")
            .Add("Н", "N")
            .Add("О", "O")
            .Add("П", "P")
            .Add("Р", "R")
            .Add("С", "S")
            .Add("Т", "T")
            .Add("У", "U")
            .Add("Ф", "F")
            .Add("Х", "H")
            .Add("Ц", "Ts")
            .Add("Ч", "Ch")
            .Add("Ш", "Sh")
            .Add("Щ", "Sch")
            .Add("Ъ", "'")
            .Add("Ы", "Y")
            .Add("Ь", "'")
            .Add("Э", "E")
            .Add("Ю", "Yu")
            .Add("Я", "Ya")
        End With

        Dim a As String = vbNullString
        For Each st As String In CmdArgs
            a = a & st & " "
        Next
        'a = Console.ReadLine

        For Each ch As Char In a
            Dim value As String = vbNullString
            If Cyrillic2Translit.TryGetValue(ch, value) Or Cyrillic2Translit.TryGetValue(Char.ToUpper(ch), value) Then
                For Each ch2 As Char In value
                    If Char.IsLower(ch) Then
                        Console.Write(Char.ToLower(ch2))
                    Else
                        Console.Write(ch2)
                    End If
                Next
            Else
                Console.Write(ch)
            End If
        Next
        Console.Read()
    End Sub
End Class

Использование Dictionary позволило избавиться от двух массивов - Cyrillic_alphabet() и Translit(). Проверку "число или нет" убрал. Пришлось добавить цикл For Each, для обеспечения корректного вывода транслита, состоящего более чем одного символа (например "Ж"-> "Zh"), так как при преобразовании с помощью Char.ToLower(ch) получалось z вместо zh. К тому же переменная value у дел, а в случаи сохранения предыдущего кода вывода (с отсеканием второго и третьего символа транслита, в случаи их присутствия) она бы просто занимала память и была использована только в качестве технического требования TryGetValue.

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Re: Перевод в транслит: как пропускать латинские символы?

Сообщение Nord777 » 25.08.2009 (Вт) 12:33

Чего то ты перемудрил с массивами.

Код: Выделить всё
      InputStr = InputStr.ToUpper()

      For Each ch As Char In InputStr.ToCharArray
         If Cyrillic2Translit.ContainsKey(ch) Then
            Console.Write(Cyrillic2Translit(ch))
         Else
            Console.Write(ch)
         End If
      Next
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5

Admiralisimys
Постоялец
Постоялец
 
Сообщения: 318
Зарегистрирован: 01.06.2009 (Пн) 10:26

Re: Перевод в транслит: как пропускать латинские символы?

Сообщение Admiralisimys » 26.08.2009 (Ср) 10:15

Nord777 я не знал как проверять наличие в словаре символа, а TryGetValue первый попавшийся мне метод подходящий под требования. Теперь буду знать и про ContainsKey, и то что ToUpper можно применять и к строкам.
Желательно сохранять регистр введённых символов, по этому возводить введенную строку в верхний регистр не нужно, а на проверке нужен ElseIf
Код: Выделить всё
        InputStr = Console.ReadLine
        For Each ch As Char In InputStr.ToCharArray
            If Cyrillic2Translit.ContainsKey(ch) Then
                Console.Write(Cyrillic2Translit(ch))
            ElseIf Cyrillic2Translit.ContainsKey(Char.ToUpper(ch)) Then
                Console.Write(Cyrillic2Translit(Char.ToUpper(ch)).ToLower)
            Else
                Console.Write(ch)
            End If
        Next

Использования ToCharArray желательно как хороший тон?

Nord777
Гуру
Гуру
Аватара пользователя
 
Сообщения: 1144
Зарегистрирован: 22.02.2004 (Вс) 13:15
Откуда: Подольск

Re: Перевод в транслит: как пропускать латинские символы?

Сообщение Nord777 » 26.08.2009 (Ср) 12:31

Использования ToCharArray желательно как хороший тон?
Нет, это я машинально написал.
ToCharArray создаёт новый массив. Конкретно в твоём примере это не нужно.
Microsoft Visual Studio 2008
Microsoft .NET Framework 3.5


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 31

    TopList