Поиск и извлечение подстрок
Применяйте string.find и string.sub для поиска и извлечения текста.
«Поиск и извлечение подстрок» — бесплатный урок Lua Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Lua Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Lua Academy содержит 4 уроков всего.
Основы string.find
string.find(s, pattern, init, plain) ищет шаблон в s, начиная с позиции init (по умолчанию — 1). Функция возвращает начальную и конечную позиции совпадения или nil, если совпадение не найдено. При plain=true шаблон воспринимается как обычная строка, без специальных символов.
local s = "hello world"
local i, j = string.find(s, "world")
print(i, j) -- 7 11
-- Plain search (literal string)
local i2, j2 = string.find("a+b=5", "+", 1, true)
print(i2, j2) -- 2 2
-- Not found
print(string.find(s, "xyz")) -- nilИзвлечение с помощью string.sub
string.sub(s, i, j) извлекает подстроку от позиции i до позиции j включительно. Отрицательные индексы отсчитываются с конца: -1 — это последний символ. Если j не указан, по умолчанию используется конец строки.
local s = "hello world"
print(string.sub(s, 1, 5)) -- hello
print(string.sub(s, 7)) -- world
print(string.sub(s, -5)) -- world
print(string.sub(s, 1, -7)) -- hello
print(s:sub(7, 11)) -- world (method syntax)Объединение find и sub
Объединяйте string.find и string.sub, чтобы находить и извлекать подстроки. Сначала найдите разделитель, затем извлеките части по обе стороны от него. Это основной подход к разделению строк.
local s = "key=value"
local i = string.find(s, "=")
if i then
local key = string.sub(s, 1, i - 1)
local val = string.sub(s, i + 1)
print(key, val) -- key value
endstring.match для захвата по шаблону
string.match(s, pattern, init) возвращает захваченные подстроки, соответствующие шаблону. Если шаблон не содержит захватов, функция возвращает всё совпадение. Если ничего не совпало, возвращается nil. Захваты задаются круглыми скобками в шаблоне.
local date = "2024-03-15"
local y, m, d = string.match(date, "(%d+)-(%d+)-(%d+)")
print(y, m, d) -- 2024 03 15
-- No capture: returns the whole match
local num = string.match("price: 42.5 USD", "%d+%.%d+")
print(num) -- 42.5Поиск последнего вхождения
Чтобы найти последнее вхождение подстроки, выполняйте поиск в цикле, каждый раз продвигая начальную позицию, или ищите с конца. Стандартный подход: вызывайте string.find, передавая позицию сразу после предыдущего совпадения, пока функция не вернёт nil.
local function findLast(s, sub)
local last_i, last_j
local i, j = string.find(s, sub, 1, true)
while i do
last_i, last_j = i, j
i, j = string.find(s, sub, j + 1, true)
end
return last_i, last_j
end
local i, j = findLast("a/b/c/d", "/")
print(i, j) -- 6 6Извлечение расширений файлов
Практический пример использования string.match: извлечение расширения из имени файла. Шаблон "([^%.]+)$" захватывает последнюю последовательность символов без точек в конце строки, а "%.([^%.]+)$" — только последовательность после последней точки.
local function getExt(filename)
return string.match(filename, "%.([^%.]+)$")
end
print(getExt("photo.jpg")) -- jpg
print(getExt("archive.tar.gz")) -- gz
print(getExt("README")) -- nil
print(getExt("config.lua.bak")) -- bakРазделение строк
В Lua нет встроенной функции разделения строк, но её можно реализовать с помощью string.gmatch. Перебирайте все последовательности символов, не являющиеся разделителями, или используйте шаблон, который захватывает содержимое между разделителями.
local function split(s, sep)
local result = {}
local pattern = "([^" .. sep .. "]+)"
for part in string.gmatch(s, pattern) do
result[#result+1] = part
end
return result
end
local parts = split("one,two,three,four", ",")
for i, p in ipairs(parts) do
print(i, p)
end
-- 1 one 2 two 3 three 4 fourУдаление пробельных символов
Удаляйте пробельные символы в начале и конце строки, сопоставляя их и отбрасывая. Шаблон "^%s*(.-)%s*$" использует ленивый квантификатор .-, чтобы захватить минимальное содержимое между необязательными пробелами в начале и конце.
local function trim(s)
return string.match(s, "^%s*(.-)%s*$")
end
print("|" .. trim(" hello ") .. "|") -- |hello|
print("|" .. trim(" \t\n") .. "|") -- ||
print("|" .. trim("no spaces") .. "|") -- |no spaces|Извлечение чисел из текста
Используйте string.gmatch с шаблоном числа, чтобы извлечь из строки все числа. Шаблон %-?%d+%.?%d* соответствует необязательному знаку минус, цифрам, необязательной десятичной точке и последующим цифрам.
local text = "Revenue: $1,234.56 Expenses: $567.89 Net: $666.67"
local numbers = {}
for n in string.gmatch(text, "%d+%.?%d*") do
numbers[#numbers+1] = tonumber(n)
end
for _, v in ipairs(numbers) do
io.write(v .. " ")
end
print() -- 1 234.0 56.0 567.89 666.67Нормализация позиций в строке
Отрицательные индексы Lua позволяют работать с конца строки. string.sub(s, -n) получает последние n символов. Для вычисления позиций используйте эту возможность вместе с #s. Понимание связи между положительными и отрицательными индексами помогает избежать ошибок на единицу.
local s = "abcdefgh"
-- Last 3 characters
print(s:sub(-3)) -- fgh
-- All but last 2
print(s:sub(1, -3)) -- abcdef
-- Character at position from end
print(s:sub(-1, -1)) -- h
print(s:sub(-4, -2)) -- efgБыстрая проверка
Что возвращает string.sub("hello", 2, -2)?
Итоги: поиск и извлечение
Краткое повторение:
string.find(s, pat, init, plain)— возвращает начальную и конечную позиции или nilstring.sub(s, i, j)— извлекает по позициям; отрицательные индексы отсчитываются с концаstring.match(s, pat)— возвращает захваты или всё совпадение- Используйте
plain=trueдля буквального поиска, без специальных символов - Реализуйте разделение строк с помощью
string.gmatch - Для удаления пробелов используйте шаблон
"^%s*(.-)%s*$"
Часто задаваемые вопросы
Урок «Поиск и извлечение подстрок» бесплатный?
Да — полный текст урока «Поиск и извлечение подстрок» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Lua Academy, подпишись на CoddyKit PRO. Курс Lua Academy содержит 4 уроков всего.
Чему я научусь в уроке «Поиск и извлечение подстрок»?
Применяйте string.find и string.sub для поиска и извлечения текста. Ты практикуешь Lua Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Lua Academy?
Предыдущий опыт не требуется. Lua Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Поиск и извлечение подстрок»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Lua Academy?
Да. Каждый урок Lua Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Основы строк: объединение и длина
- Поиск и извлечение подстрок
- string.format для вывода
- string.gsub и string.gmatch