【问题标题】:regex replace : if not followed by letter or number正则表达式替换:如果后面没有字母或数字
【发布时间】:2015-03-31 15:48:58
【问题描述】:

好的,所以我想要一个正则表达式来解析 uncontracted(如果这就是所谓的)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 :

【问题讨论】:

  • this,但这不适用于 Lua(我对任何可行的想法都一无所知)。
  • Lua 模式匹配不是标准正则表达式。

标签: regex string lua lua-patterns


【解决方案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

【讨论】:

    【解决方案2】:

    没有单一的语句模式可以做到这一点,但你可以使用一个函数来为任何可能的输入做到这一点:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-02
      • 1970-01-01
      • 1970-01-01
      • 2022-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多