Толик Панков
hex_laden
............ .................. ................

October 2025
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Back November 26th, 2022 Forward
Lazarus: Транслит строки (в консоли)

1. Понадобятся модули regexpr и fgl:

uses regexpr, fgl;

regexpr нужен для небольшой оптимизации, a fgl - для создания аналога словаря (Dictionary).

2. Создаем тип для будущего словаря:

type
  TDictTrans=class(specialize TFPGMap<string, string>);


Документация по TFPGMap

3. Сделаем функцию для транслитерации, с одним параметром, входной строкой с русскими буквами:

function Translit(Str:string):string;
//тут будет код
end;


4. Заводим внутренние переменные функции:

var Regex:TRegExpr;
Dict:TDictTrans;
Ch,oStr,oTrans:string;
I:LongInt;


Regex - экземпляр класса для работы с регулярным выражением.
Dict - словарь для транслитерации.
Ch - транслитерируемый символ
oStr - выходная строка
oTrans - сюда будем возвращать результат транслита отдельного символа.
I - счетчик цикла, в котором будем анализировать строку.

Небольшая оптимизация


Создаем новое регулярное выражение для кириллицы (и пробела) и проверяем входную строку на наличие русских букв. Если их нет - возвращаем исходную строку и выходим из функции:

Regex:=TRegExpr.Create;
Regex.Expression:='[А-Я]|[а-я]|\s';
if not Regex.Exec(Str) then begin
   exit(Str);
end;


5. Заполняем словарь (транслит взят из старого армейского учебника времен СССР, можете сделать свой):

Dict:=TDictTrans.Create;
Dict.Add(' ','_');
Dict.Add('А','A'); Dict.Add('а','a');
...
Dict.Add('Я','JA'); Dict.Add('я','ja');


Словарь целиком на PasteBin

6. Инициализируем переменные, используемые в цикле:

Ch:=''; oStr:='';

7. Заводим цикл for, нумерация символов в строке идет с 1, длина строки получается функцией Length(Str):

for I:=1 to Length(Str) do begin
...
end;


8. В цикле получаем символ из строки:

Ch:=Copy(Str,I,1);

9. Пробуем получить данные из словаря по ключу, которым является русская буква. Если это удалось, присоединяем результат транслита к выходной строке, если нет - это не русская буква, присоединяем исходный символ к выходной строке:

if Dict.TryGetData(Ch, oTrans) then begin
	oStr:=oStr+oTrans; //russkaya bukva - transliteriruem
end
else begin
	oStr:=oStr+Ch; //nerusskaya bukva, ostavlaem v pokoe
end;


10. Освобождаем память словаря после цикла:

Dict.Free;

11. Возвращаем результат работы функции:

exit(oStr);

Функция целиком на PasteBin

12. Код основной программы:
var
    strInput, strOutput:string;
...
begin
  Write('Input string:'); ReadLn(strInput);
  strOutput:=Translit(strInput);
  WriteLn(strOutput);
  WriteLn('Press Enter...'); ReadLn();
end.


Для совместимости с русским языком в консоли необходимо добавить директивы компилятора, иначе словарь будет работать неправильно:

program translit;
{$mode objfpc} {H+}
{$codepage CP866}
...


$mode objfpc
H+ - чтоб строки по умолчанию не были ShortString'ами
$codepage CP866 - установка кодовой страницы.

Документация по работе со строками

Проверка




Исходник примера на GitHub

Это репост с сайта http://tolik-punkoff.com
Оригинал: https://tolik-punkoff.com/2022/11/26/lazarus-translit-stroki-v-konsoli/

Tags: ,
Back November 26th, 2022 Forward