Перейти к публикации
Форум - ComputerCraft
  • 0
Stinger

Регулярное Выражение

Вопрос

Здравствуйте, возможно есть у кого то регулярное выражение на домены для lua, сам к сожалению не могу составить такое, пока не изучал регулярные выражения а именно интересует отсеивание ссылок любого типа от yandex.ru до яндекс.рф.


Изменено пользователем Stinger

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Рекомендованные сообщения

  • 0

Не получается вообще ни в какую, может есть функция которая разбивает строку на символы и пробегает по массиву заменяя их на маленькие

 

Если Lua-интерпретатор вшит в скомпилированное .exe-приложение, то крайне маловероятно, что тебе удастся прикрутить стороннюю либу без продажи души дьяволу. Также штатными средствами без поддержки юникода разбить строку на юникод-символы не представляется возможным, так как любая строка в Lua - это последовательность байт, воспринимаемых string-библиотекой в виде ASCII-символов.

 

Однако это не значит, что проблема не решаема. Для начала тебе потребуется написать собственный костыль, разбивающий строку на составляющие байты и загоняющий их в байт-массив, делается это дефолтным string.byte() с указанным диапазоном:

 

na4UKyy.png?1

local stroka = "Привет"
local bytes = {string.byte(stroka, 1, #stroka)}

Затем придется перебирать полученный байт-массив итеративно и вручную извлекать из него UTF-8 символы, используя бинарные операции. Обратимся к великой и могучей Википедии, чтобы разобраться в структуре кодирования данных в UTF-8:

 

rdo3XQV.png?1

 

В целом все довольно просто: каждый символ - это последовательность нескольких байт. Чтобы определить количество байт в последовательности, необходимо специфичным образом обработать первый байт из последовательности. Для этого находим в нем первый "нолик слева" и считаем число "единичек до нолика" - это самое количество единичек и будет количеством байт, необходимых для кодирования выбранного символа.

 

Дальше - дело техники. Зная размерность символа, ты можешь легко извлечь эти байты из массива байт через table.unpack(), затем "склеить" их в символ через string.char(), а потом уже работать с получившимся символом так, как тебе требуется. Чтобы не ходить вокруг да около, держи рабочий скрипт:

local function getUTF8Chars(stroka)
  -- Получаем байт-последовательность указанной строки
  local bytes = {string.byte(stroka, 1, #stroka)}
  local symbols = {}

  -- Перебираем все имеющиеся байты
  local i = 1
  while i <= #bytes do
    -- Определяем позицию нулевого бита в первом байте UTF-8 символа. Это же число и будет размером символа
    local utf8CharSize = 1
    for j = 1, 7 do
      if bit32.band(bit32.rshift(bytes[i], 8 - j), 0x1) == 0x0 then
        utf8CharSize = j
        break
      end
    end   

    -- Если размер символа единичный, то используем все тот же байт для его идентификации
    if utf8CharSize == 1 then
      table.insert(symbols, string.char(bytes[i]))
      i = i + 1
    -- В противном случае используем последовательность байт
    else
      table.insert(symbols, string.char(table.unpack(bytes, i, i + utf8CharSize - 2)))
      i = i + utf8CharSize - 1
    end
  end

  return symbols
end

-- Переводим любую входную строку в массив UTF-8 символов
local chars = getUTF8Chars("Hello, юникод")
for i = 1, #chars do
  print(chars[i])
end

В результате его выполнения ты получишь вполне себе операбельный массив символов, с которым можешь делать все, что заблагорассудится.

 

my66STC.png?1

 

При пробелах находить это же слово, вот так М а т

Используй stroka:gsub("%s+", "") для удаления пробелов. Если работа с UTF-8 все же будет кривой - напиши функцию, перебирающую полученный выше массив символов и удаляющую из него пробелы:

local function removeWhitespaces(chars)
  local i = 1
  while i <= #chars do
    if chars[i] == " " then
      table.remove(chars, i)
    else
      i = i + 1
    end
  end
end

Перевести текст Unicode в нижний регистр

 

Теперь что касается конвертации регистра - тут уже все не столь однозначно. Под каждую языковую группу зарезервирован определенный диапазон кодов - и, в зависимости, от размера алфавита, его размер также различается: к примеру, все буквы русского языка умещаются в 64 байт-последовательности, а английского - уже в 52. При этом сначала перечисляются буквы в верхнем регистре, а затем уже в нижнем. Соответственно, для "изменения" регистра в русском алфавите с верхнего на нижний достаточно прибавить к коду буквы 32, ну, а для обратной конвертации использовать уже вычитание. Отсюда можно сделать вывод, что без указания конкретного языкового диапазона прямая конвертация невозможна, и следует создать таблицы символов в верхнем и нижнем регистрах, а затем уже выбирать из них необходимые данные:

local cases = {
  ["а"] = "А",
  ["б"] = "Б",
  ...
}

Безусловно, такой подход крайне неэффективен, но что поделать?

Изменено пользователем ECS
  • Like 4

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Домены или ссылки? :)

 

Скорее домены, думаю так эффективнее ибо не каждый использует http:// и www, спасибо за поправку.

Изменено пользователем Stinger

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

А какая задача конкретно преследуется?

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

-- Следующая

 

if message == link then

 

return 0

 

Ещё столкнулся с проблемой string.lower не работает с Unicode

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Вот такой простой вариант: ^[%w][%w%-%.%+]

!Не работает с юникодом!

А по поводу

string.lower()
юзай модуль unicode
  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Делюсь наработкой:

 

local word = {
"мат",
"mat"
}

if (string.find(message, "[A-z0-9][.][A-z0-9]")) then
Message(player,"Обнаружена реклама, сообщение не отправлено!")
return 0
end

for i = 1 , size(word), 1 do

if (string.find(string.lower(message), word[i]) ~= nil) then
Message(player,"Обнаружено плохое слово, сообщение не отправлено!")
return 0
end

end

 
И если написать слово так englis h то уже пропускает, как бы это решить есть идеи ?
 

Вот такой простой вариант: ^[%w][%w%-%.%+]
!Не работает с юникодом!
А по поводу

string.lower()
юзай модуль unicode

 

 
Я бы с радостью, да вот игра устарела и lua 5.0 вшито в .exe и обновить версию lua не представляется возможным.

 

На данный момент проблемы 2!

 

1) Перевести текст Unicode в нижний регистр.

 

2) При пробелах находить это же слово, вот так М а т.

Изменено пользователем Stinger

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Как нибудь можно впаять модуль Unicode в lua 5.0 ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

 

Не получается вообще ни в какую, может есть функция которая разбивает строку на символы и пробегает по массиву заменяя их на маленькие ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

@@ECS

Спасибо, буду пробовать)

Изменено пользователем eu_tomat
Черезмерное цитирование

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

 

Если Lua-интерпретатор вшит в скомпилированное .exe-приложение, то крайне маловероятно, что тебе удастся прикрутить стороннюю либу без продажи души дьяволу. Также штатными средствами без поддержки юникода разбить строку на юникод-символы не представляется возможным, так как любая строка в Lua - это последовательность байт, воспринимаемых string-библиотекой в виде ASCII-символов.

 

 

Ругается на эту строку:

 

attempt to index global `bit32' (a nil value)

 

символы которые выделил чёрным, не пропускает без ковычек.

 

if bit32.band(bit32.rshift(bytes, 8 - j), 0x1) == 0x0 then

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

 

 

if bit32.band(bit32.rshift(bytes, 8 - j), 0x1) == 0x0 then

 

Замени на 1 и 0 соответственно. 

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Если Lua-интерпретатор вшит в скомпилированное .exe-приложение, то крайне маловероятно, что тебе удастся прикрутить стороннюю либу без продажи души дьяволу. Также штатными средствами без поддержки юникода разбить строку на юникод-символы не представляется возможным, так как любая строка в Lua - это последовательность байт, воспринимаемых string-библиотекой в виде ASCII-символов.

 

Однако это не значит, что проблема не решаема. Для начала тебе потребуется написать собственный костыль, разбивающий строку на составляющие байты и загоняющий их в байт-массив, делается это дефолтным string.byte() с указанным диапазоном:

 

...

 

Безусловно, такой подход крайне неэффективен, но что поделать?

 

Ребят , если кому интересно даю ответ, все мы копали не там!

 

--Проверено в lua 5.0
 
 os.setlocale ("", "ctype") -- Добавляем волшебную строку перед выводом, указываем параметр, что бы не возникало проблем с цифрами!

print("Оригинальное сообщение: " .. message)
print("нижний регистр: " .. string.lower(message))
print("ВЕРХНИЙ РЕГИСТР: " .. string.upper(message))

Отпишу дальше, что получилось и поделюсь кодом, может кому то пригодиться.

Изменено пользователем Stinger
гигантские цитаты убираем, код кладём в тег <code>

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Появился вопрос, можно ли как-то в регулярном выражении задать кол-во символов ? В php я бы решил это так {1,4} , тут такое не работает!

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Ну так в луа и не регулярные выражения! Здесь гораздо более простой аналог — шаблоны. Ещё раз: это не регулярные выражения, ни в коем случае, — шаблоны. Никаких повторений, именованных групп и прочего нет. Обходи повторением элементов шаблона.

 

Инфа по шаблонам: гайд, рецепт.

  • Like 4

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Ну так в луа и не регулярные выражения! Здесь гораздо более простой аналог — шаблоны. Ещё раз: это не регулярные выражения, ни в коем случае, — шаблоны. Никаких повторений, именованных групп и прочего нет. Обходи повторением элементов шаблона.

 

Инфа по шаблонам: гайд, рецепт.

 

Спасибо

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас

×