185 lines
7.1 KiB
Plaintext
185 lines
7.1 KiB
Plaintext
модуль строка
|
||
|
||
импорт "стд::строки"
|
||
импорт "стд::юникод"
|
||
импорт "исх/массивы"
|
||
|
||
тип Байты = []Байт
|
||
|
||
фн 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' иначе прервать
|
||
}
|
||
вернуть ложь
|
||
}
|