модуль строка импорт "стд::строки" импорт "стд::юникод" импорт "исх/массивы" тип Байты = []Байт фн tri_substring(с: Строка8, первый-байт: Цел64, число-байтов: Цел64): Строка @внеш фн tri_substring_from_bytes(байты: Байты, первый-байт: Цел64, число-байтов: Цел64): Строка @внеш фн заменить*(с: Строка, подстрока: Строка, замена: Строка): Строка { надо длина(подстрока) > 0 иначе вернуть с пусть с8 = с(:Строка8) пусть п8 = подстрока(:Строка8) пусть № := индекс(с, 0, подстрока) надо № >= 0 иначе вернуть с пусть сб = строки.Сборщик{} пусть №-старт := 0 пока истина { сб.добавить строку(строки.извлечь(с8(:Строка), №-старт, № - №-старт)) сб.добавить строку(замена) №-старт := № + длина(п8) № := индекс(с, №-старт, подстрока) надо № >= 0 иначе прервать надо №-старт < длина(замена) иначе прервать } сб.добавить строку(строки.извлечь(с8(:Строка), №-старт, длина(с8) - №-старт)) вернуть сб.строка() } фн разобрать*(с: Строка, разделитель: Строка): массивы.Строки { пусть р8 = разделитель(:Строка8) выбор длина(р8) { когда 0: вернуть массивы.Строки[с] когда 1: вернуть разобрать1(с, р8[0]) другое авария("не реализовано - длина разделителя > 1") } вернуть массивы.Строки[] } фн соединить*(разделитель: Строка, строчки: ...Строка): Строка { вернуть строки.соединить(разделитель, строчки...) } фн ф*(формат: Строка, аргументы: ...*): Строка { пусть сб = строки.Сборщик{} сб.ф(формат, аргументы...) вернуть сб.строка() } фн разобрать1(с: Строка, разделитель: Байт): массивы.Строки { пусть рез = массивы.Строки[] пусть с8 = с(:Строка8) пусть № := 0 пусть №-разд := -1 пока № < длина(с8) { если с8[№] = разделитель { если №-разд + 1 = № { рез.добавить("") } иначе { рез.добавить(tri_substring(с8, №-разд+1, № - №-разд - 1)) } №-разд := № } №++ } рез.добавить(tri_substring(с8, №-разд+1, длина(с8) - №-разд - 1)) вернуть рез } фн собрать*(список строк: ...Строка): Строка { надо длина(список строк) > 0 иначе вернуть "" пусть размер := 0 пусть № := 0 пока № < длина(список строк) { размер := размер + длина(список строк[№](:Строка8)) №++ } пусть сб = строки.Сборщик{} № := 0 пока № < длина(список строк) { сб.добавить строку(список строк[№]) №++ } вернуть сб.строка() } фн индекс*(с: Строка, №-старт: Цел64, подстрока: Строка): Цел64 { вернуть строки.индекс(с, №-старт, подстрока) } фн извлечь*(с: Строка, №-байта: Цел64, число-байтов: Цел64): Строка { вернуть строки.извлечь(с, №-байта, число-байтов) } фн обрезать пробельные символы*(с: Строка): Строка { пусть с8 = с(:Строка8) пусть №1 := 0 пока №1 < длина(с8) { надо с8[№1] < 0x80(:Байт) иначе прервать надо юникод.пробельный символ?(с8[№1](:Символ)) иначе прервать №1++ } пусть №2 := длина(с8) пока №2 > №1 { пусть байт = с8[№2-1] надо байт < 0x80(:Байт) иначе прервать надо юникод.пробельный символ?(байт(:Символ)) иначе прервать №2-- } вернуть tri_substring(с8, №1, №2 - №1) } фн разделить*(с: Строка, разделитель: Строка, первая := Строка, вторая := Строка): Лог { пусть и = индекс(с, 0, разделитель) надо и >= 0 иначе { первая := с вторая := "" вернуть ложь } пусть с8 = с(:Строка8) пусть р8 = разделитель(:Строка8) первая := tri_substring(с8, 0, и) вторая := tri_substring(с8, и + длина(р8), длина(с8) - (и +длина(р8))) вернуть истина } фн извлечь цел*(с: Строка, №-байта := Цел64, рез := Цел64): Лог { рез := 0 пусть с8 = с(:Строка8) надо №-байта < длина(с8) иначе вернуть ложь пусть нег = с8[№-байта] = '-'(:Байт) если нег | с8[№-байта] = '+'(:Байт) { №-байта++ надо №-байта < длина(с8) иначе вернуть ложь } пусть сим := с8[№-байта](:Символ) надо сим >= '0' & сим <= '9' иначе вернуть ложь пусть число := 0 пока истина { пусть цифра = сим(:Цел64) - '0'(:Цел64) // проверка выхода за границу надо число <= (0x7FFFFFFFFFFFFFFF(:Цел64) - цифра) / 10 иначе вернуть ложь число := число*10 + цифра №-байта++ если №-байта >= длина(с8) { если нег { число := - число } рез := число вернуть истина } сим := с8[№-байта](:Символ) надо сим >= '0' & сим <= '9' иначе прервать } вернуть ложь }