регулярное выражение replace : если за ним не следует буква или цифра

Хорошо, поэтому я хотел, чтобы регулярное выражение анализировало неконтрактные (если это так называется) адреса ipv6.

Пример IPv6-адреса: 1050:::600:5:1000::

Что я хочу вернуть: 1050:0000:0000:600:5:1000:0000:0000

Моя попытка:

ip:gsub("%:([^0-9a-zA-Z])", ":0000")

Первая проблема с этим: Заменяет первый и второй :

Таким образом, :: заменяется на :0000.

Замена его на :0000: не сработает, потому что тогда он будет заканчиваться на :. Также это заметит, что синтаксический анализ недавно добавленного : приводит к: 1050:0000::600:5:1000:0000:

Итак, для чего мне нужно это регулярное выражение?

Замените каждое : на :0000, если за ним не следует цифра или буква.

Основная проблема: :: заменяется вместо 1 :


person PrivateerGerrit    schedule 31.03.2015    source источник
comment
Есть это, но это не будет работать с Lua (я отказываюсь от любых идей, которые должно сработать).   -  person Sam    schedule 31.03.2015
comment
Сопоставление с образцом Lua не является стандартным регулярным выражением.   -  person badcc    schedule 01.04.2015


Ответы (2)


gsub и другие функции из библиотеки строк Lua используют шаблоны Lua, которые намного проще, чем регулярное выражение. Использование шаблона более одного раза будет обрабатывать случаи, когда шаблон перекрывает замещающий текст. Шаблон нужно применять только дважды, так как в первый раз будут обнаружены четные пары, а во второй — нечетные/новые пары двоеточий. Замыкающие и ведущие двоеточия можно обрабатывать отдельно с помощью собственных шаблонов.

ip = "1050:::600:5:1000::"
ip = ip:gsub("^:", "0000:"):gsub(":$", ":0000")
ip = ip:gsub("::", ":0000:"):gsub("::", ":0000:")
print(ip) -- 1050:0000:0000:600:5:1000:0000:0000
person ryanpattison    schedule 31.03.2015

Для этого нет единого шаблона оператора, но вы можете использовать функцию, чтобы сделать это для любого возможного ввода:

function fill_ip(s)
  local ans = {}
  for s in (s..':'):gmatch('(%x*):') do
    if s == '' then s = '0000' end
    ans[ #ans+1 ] = s
  end
  return table.concat(ans,':')
end

--examples:
print(fill_ip('1050:::600:5:1000::'))
print(fill_ip(':1050:::600:5:1000:'))
print(fill_ip('1050::::600:5:1000:1'))
print(fill_ip(':::::::'))
person tonypdmtr    schedule 31.03.2015