正则表达式替换:如果没有后跟字母或数字

时间:2015-03-31 15:48:58

标签: regex string lua lua-patterns

好吧所以我想要一个正则表达式来解析未收缩的(如果这就是所谓的)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 {{1}}

2 个答案:

答案 0 :(得分:1)

gsub和Lua的字符串库中的其他函数使用Lua Patterns,它们比正则表达式简单得多。多次使用该模式将处理模式与替换文本重叠的情况。该模式只需要应用两次,因为第一次将捕获偶数配对,第二次将捕获奇数/新配对的冒号。尾随和前导冒号可以用自己的模式单独处理。

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

答案 1 :(得分:1)

没有单一的语句模式可以执行此操作,但您可以使用函数对任何可能的输入执行此操作:

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(':::::::'))