Перейти к содержимому


Фотография

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


Лучший Ответ ECS , 04 Декабрь 2017 - 13:25

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

 
Если 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 = {
  ["а"] = "А",
  ["б"] = "Б",
  ...
}

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

Перейти к сообщению


  • Авторизуйтесь для ответа в теме
Сообщений в теме: 17

#1 Оффлайн   Stinger

Stinger
  • Пользователи
  • Сообщений: 38
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Отправлено 03 Декабрь 2017 - 10:05

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


Сообщение отредактировал Stinger: 03 Декабрь 2017 - 11:24


#2 Оффлайн   Zabqer

Zabqer
  • Пользователи
  • Сообщений: 17
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Отправлено 03 Декабрь 2017 - 11:08

Домены или ссылки? :)
  • Stinger это нравится

#3 Оффлайн   Stinger

Stinger
  • Автор темы
  • Пользователи
  • Сообщений: 38
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Отправлено 03 Декабрь 2017 - 11:24

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

 

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


Сообщение отредактировал Stinger: 03 Декабрь 2017 - 11:25


#4 Оффлайн   Zabqer

Zabqer
  • Пользователи
  • Сообщений: 17
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Отправлено 03 Декабрь 2017 - 11:59

А какая задача конкретно преследуется?
  • Stinger это нравится

#5 Оффлайн   Stinger

Stinger
  • Автор темы
  • Пользователи
  • Сообщений: 38
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Отправлено 03 Декабрь 2017 - 12:08

-- Следующая

 

if message == link then

 

return 0

 

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



#6 Оффлайн   Zabqer

Zabqer
  • Пользователи
  • Сообщений: 17
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Отправлено 03 Декабрь 2017 - 12:22

Вот такой простой вариант: ^[%w][%w%-%.%+]
!Не работает с юникодом!
А по поводу
string.lower()
юзай модуль unicode
  • Stinger это нравится

#7 Оффлайн   Stinger

Stinger
  • Автор темы
  • Пользователи
  • Сообщений: 38
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Отправлено 03 Декабрь 2017 - 12:25

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

 

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: 03 Декабрь 2017 - 15:48


#8 Оффлайн   Stinger

Stinger
  • Автор темы
  • Пользователи
  • Сообщений: 38
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Отправлено 03 Декабрь 2017 - 19:08

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



#9 Оффлайн   NEO

NEO
  • Пользователи
  • Сообщений: 1 691
  • Уровень сигнала: 3,96%
  • В игре: 24 час. 15 мин.
  • ГородСолнце

Награды

   2                        

Отправлено 03 Декабрь 2017 - 22:09

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

https://github.com/starwing/luautf8


  • Stinger это нравится

#10 Оффлайн   Stinger

Stinger
  • Автор темы
  • Пользователи
  • Сообщений: 38
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Отправлено 04 Декабрь 2017 - 04:02

 

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



#11 Оффлайн   ECS

ECS
  • Гуру
  • Сообщений: 161
  • Уровень сигнала: 0,04%
  • В игре: 0 час. 13 мин.
  • ГородСанкт-Петербург

Награды

      7               

Отправлено 04 Декабрь 2017 - 13:25   Лучший Ответ

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

 
Если 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: 04 Декабрь 2017 - 17:54

  • Zer0Galaxy, NEO, Totoro и еще 1 это нравится

#12 Оффлайн   Stinger

Stinger
  • Автор темы
  • Пользователи
  • Сообщений: 38
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Отправлено 04 Декабрь 2017 - 22:59

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

Сообщение отредактировал eu_tomat: 05 Декабрь 2017 - 00:55
Черезмерное цитирование


#13 Оффлайн   Stinger

Stinger
  • Автор темы
  • Пользователи
  • Сообщений: 38
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Отправлено 05 Декабрь 2017 - 02:50

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

 

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

 

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

 

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

 

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



#14 Оффлайн   Totoro

Totoro
  • Хранители Кода
  • Сообщений: 1 683
  • Уровень сигнала: 0,36%
  • В игре: 2 час. 13 мин.

Награды

                                      

Отправлено 05 Декабрь 2017 - 14:53

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

 

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


  • Stinger это нравится

#15 Оффлайн   Stinger

Stinger
  • Автор темы
  • Пользователи
  • Сообщений: 38
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Отправлено 05 Декабрь 2017 - 17:12

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

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

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

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

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

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


Сообщение отредактировал Stinger: 06 Декабрь 2017 - 08:17
гигантские цитаты убираем, код кладём в тег <code>


#16 Оффлайн   Stinger

Stinger
  • Автор темы
  • Пользователи
  • Сообщений: 38
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Отправлено 06 Декабрь 2017 - 06:41

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



#17 Оффлайн   Fingercomp

Fingercomp
  • Гуру
  • Сообщений: 1 958
  • Уровень сигнала: 187,35%
  • В игре: 1148 час. 24 мин.

Награды

                                               

Отправлено 06 Декабрь 2017 - 08:57

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

 

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


  • Totoro, eu_tomat, ECS и еще 1 это нравится

#18 Оффлайн   Stinger

Stinger
  • Автор темы
  • Пользователи
  • Сообщений: 38
  • Уровень сигнала: 0%
  • В игре: 0 час. 0 мин.

Отправлено 06 Декабрь 2017 - 15:13

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

 

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

 

Спасибо






Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных

Яндекс.Метрика