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/laz