Files
srab/исх/строка/строка.tri
2025-11-26 21:32:41 +03:00

185 lines
7.1 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
модуль строка
импорт "стд::строки"
импорт "стд::юникод"
импорт "исх/массивы"
тип Байты = []Байт
фн 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' иначе прервать
}
вернуть ложь
}