Перед началом прочтения данной статьи ознакомьтесь с
Попытаюсь максимально подробно расписать базовые варианты, которые надо людям в 99% случаях. Остальные варианты подставить самим вам уже не составит после прочтению этой статьи (надеюсь).
Для начала рассмотрим методы find и match.
find - возвращает позицию подстроки в строке. Принимает 4 параметра. Мы же будем использовать только 2: строку в которой будет искать, и шаблон который будем искать.
match - ищет первое вхождение шаблона в строку, возвращая захваченные значения. Принимает 3 параметра. Мы же будем использовать только 2: строку в которой будет искать, и шаблон который будем искать.
Рассмотрим первый банальный пример, который я придумал только что.
Давайте достанем отсюда Имя второго собеседника, и возраст.
Какие точки с минусами я натолкал. Давайте разберем. После прочтения текста в ссылках в начале темы вы уже могли догадаться что это и есть те самые регулярные выражения.
. (точка) соответствует любому символу.
+ (плюс) соответствует неограниченному повторению. Эти символы будут всегда соответствовать самой длинной возможной последовательности.
- (минус) соответствует неограниченному повторению. Эти символы будут всегда соответствовать самой короткой возможной последовательности. Т.е например после пробела оно уже не будет работать. Рассмотрим чуть позже это.
%d соответствует любой цифре.
Если регулярные выражения в находятся в скобках, это значит что match их захватит и мы сможем их поместить в переменную.
Возвращаемся к нашему примеру. Мы ему указали что нам надо захватить самую короткую возможную последовательность после слова "Привет". дальше мы указали что в строке присутствует еще текст после слова "зовут", но поскольку он не находится в скобках - метод match его не захватит. Дальше мы указываем что в строке после слова "мне" есть какое то число. Поскольку выражение находится в скобках - match его захватит.
Давайте рассмотрим отличия .+ и .-.
Представим что в каком то хуке в переменную text нам прилетело сообщение
Поставим .+ т.е самую длинную возможную последовательность.
Поставим .- т.е самую короткую возможную последовательность
Думаю понятно. Ничего сложного в этом нет.
В своем коде вам нужно их экранировать. Экранирование осуществляется при помощи символа %.
Рассмотрим пример.
Представим что нам нужно узнать профессию, имя и то, что человек говорит. Если мы сделаем так как делали чуточку выше, а именно
То у нас ничего не сработает по 1 понятной причине, а именно из-за [] которые относятся к волшебным символам, а их, в свою очередь, нужно экранировать. Посмотрим на правильный вариант:
Важно: внимательные уже заметили, что знак экранирования(процент (%)) тоже относится к волшебным символам, и экранируется он особенно, а именно двумя процентами. Можно и одним, но если у вас возникнут проблемы - будете виноваты сами, потому что я не помню зачем там 2 процента, но помню что надо :D. Для примера возьмем
И вытащим отсюда процентную ставку в процентах.
Возьмем этот же пример, но уберем +, и на выходе получим первую цифру
Получим все, кроме цифр (до первой цифры) из строки:
В коде выше мы распределяем текст по аргументам, а потом проверяем их на nil. Т.е если нужный нам текст не появился - ничего не произойдет, так как содержимое переменных будет nil, ну а как только появился - выполнится код.
Вроде бы все объяснил и упомянул. Если что-то забыл - напишите об этом ниже.
- http://umodel.narod.ru/webhelp/ams/Program_Reference/Actions/RegExp_Lua.htm
- https://user.su/lua/index.php?id=9
Попытаюсь максимально подробно расписать базовые варианты, которые надо людям в 99% случаях. Остальные варианты подставить самим вам уже не составит после прочтению этой статьи (надеюсь).
Для начала рассмотрим методы find и match.
find - возвращает позицию подстроки в строке. Принимает 4 параметра. Мы же будем использовать только 2: строку в которой будет искать, и шаблон который будем искать.
match - ищет первое вхождение шаблона в строку, возвращая захваченные значения. Принимает 3 параметра. Мы же будем использовать только 2: строку в которой будет искать, и шаблон который будем искать.
Рассмотрим первый банальный пример, который я придумал только что.
Lua:
text = 'Привет Сеня, меня зовут Дима, мне 18 лет, а тебе сколько?' -- строка которую мы будем обрабатывать
Lua:
text = 'Привет Сеня, меня зовут Дима, мне 18 лет, а тебе сколько?' -- строка которую мы будем обрабатывать
if string.find(text--[[строка в которой ищем текст]], 'Привет (.-), меня зовут .-, мне (%d+) лет, а тебе сколько?'--[[шаблон который надо искать]]) then
end
. (точка) соответствует любому символу.
+ (плюс) соответствует неограниченному повторению. Эти символы будут всегда соответствовать самой длинной возможной последовательности.
- (минус) соответствует неограниченному повторению. Эти символы будут всегда соответствовать самой короткой возможной последовательности. Т.е например после пробела оно уже не будет работать. Рассмотрим чуть позже это.
%d соответствует любой цифре.
Если регулярные выражения в находятся в скобках, это значит что match их захватит и мы сможем их поместить в переменную.
Возвращаемся к нашему примеру. Мы ему указали что нам надо захватить самую короткую возможную последовательность после слова "Привет". дальше мы указали что в строке присутствует еще текст после слова "зовут", но поскольку он не находится в скобках - метод match его не захватит. Дальше мы указываем что в строке после слова "мне" есть какое то число. Поскольку выражение находится в скобках - match его захватит.
Lua:
text = 'Привет Сеня, меня зовут Дима, мне 18 лет, а тебе сколько?' -- строка которую мы будем обрабатывать
if string.find(text--[[строка в которой ищем текст]], 'Привет (.-), меня зовут .-, мне (%d+) лет, а тебе сколько?'--[[шаблон который надо искать]]) then
name, age --[[указываем переменные в которые нужно поместить текст]]= string.match(text--[[строка в которой ищем текст]], 'Привет (.-), меня зовут .-, мне (%d+) лет, а тебе сколько?'--[[шаблон который надо искать]])
print(name, age) -- Выводим содержимое переменных. Т.е данный код выведет "Сеня 18"
end
Давайте рассмотрим отличия .+ и .-.
Представим что в каком то хуке в переменную text нам прилетело сообщение
Lua:
text = 'Продам коня с бронзовым копытом. Цена договорная'
Lua:
text = 'Продам коня с бронзовым копытом. Цена договорная'
if string.find(text, 'Продам (.+)') then
var = string.match(text, 'Продам (.+)')
print(var)
end
Lua:
--output << коня с бронзовым копытом. Цена договорная
Lua:
text = 'Продам коня с бронзовым копытом. Цена договорная'
if string.find(text, 'Продам (.-)') then
var = string.match(text, 'Продам (.-) ')
print(var)
end
Lua:
--output << коня
Волшебные символы
В регулярных выражениях луа присутствуют волшебные символы, а именно ^$()%.[]*+-?В своем коде вам нужно их экранировать. Экранирование осуществляется при помощи символа %.
Рассмотрим пример.
Lua:
text = '[Сантехник] Николай говорит: куплю коня.'
Неправильный вариант:
text = '[Сантехник] Николай говорит: куплю коня.'
if string.find(text, '[(.-)] (.-) говорит: (.+)') then
profession, name, msg = string.match(text, '[(.-)] (.-) говорит: (.+)')
print(profession, name, msg)
end
Правильный вариант:
text = '[Сантехник] Николай говорит: куплю коня.'
if string.find(text, '%[(.-)%] (.-) говорит: (.+)') then
profession, name, msg = string.match(text, '%[(.-)%] (.-) говорит: (.+)')
print(profession, name, msg)
end
Lua:
--output << Сантехник Николай куплю коня.
Важно: внимательные уже заметили, что знак экранирования(процент (%)) тоже относится к волшебным символам, и экранируется он особенно, а именно двумя процентами. Можно и одним, но если у вас возникнут проблемы - будете виноваты сами, потому что я не помню зачем там 2 процента, но помню что надо :D. Для примера возьмем
Lua:
text = 'Процентная ставка составляет 3%!'
Lua:
text = 'Процентная ставка составляет 3%!'
if string.find(text, 'Процентная ставка составляет (%d+)%%%!') then
rate = string.match(text, 'Процентная ставка составляет (%d+)%%%!')
print(rate)
end
Lua:
--output << 3
Упрощаем код.
Выше я использовал string.find и string.match, но эти методы можно использовать напрямую. Тут на самом деле нечего расписывать, я попросту пример про сантехника который наводил чуть выше, и покажу как его можно оформить этим способом.
Lua:
text = '[Сантехник] Николай говорит: куплю коня.'
if text:find('%[(.-)%] (.-) говорит: (.+)') then -- мы избавились от первого аргумента, так как применяем функцию к конкретной переменной, в нашем случае к переменной text
profession, name, msg = text:match('%[(.-)%] (.-) говорит: (.+)') -- аналогичная ситуация
print(profession, name, msg)
end
Примерчики на счет цифр и чисел.
Возьмем следующий код, а именно получим число
Lua:
text = 'Сходил я в этот ваш барбершоп, правда не понял за что 3000 отдал.'
if text:find('(%d+)') then
print(text:match('(%d+)'))
end
--output << 3000
Lua:
text = 'Сходил я в этот ваш барбершоп, правда не понял за что 3000 отдал.'
if text:find('(%d)') then
print(text:match('(%d)'))
end
--output << 3
Lua:
text = 'Сходил я в этот ваш барбершоп, правда не понял за что 3000 отдал.'
if text:find('(%D+)') then
print(text:match('(%D+)'))
end
--output << Сходил я в этот ваш барбершоп, правда не понял за что
Оптимизация сценария.
Возьмем тот же пример с сантехником. Использование и find и match там не обязательно, ведь мы же знаем что будем получать аргументы, зачем нам финд? Рассмотрим оптимизированный вариант:
Lua:
text = '[Сантехник] Николай говорит: куплю коня.'
profession, name, msg = text:match('%[(.-)%] (.-) говорит: (.+)')
if profession and name and msg then
print(profession, name, msg)
end
Вроде бы все объяснил и упомянул. Если что-то забыл - напишите об этом ниже.
Последнее редактирование: