2015-03-31 90 views
3

好了,所以我需要一個正則表達式來解析非收縮(如果這就是它被稱爲)的IPv6不會忽略正則表達式替換:如果後面沒有字母或數字

例的IPv6地址:1050:::600:5:1000::

我想要什麼返回: 1050:0000:0000:600:5:1000:0000:0000

我試試這個:

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

第一PR oblem與此:它取代了第一和第二:

所以::獲取與:0000

:0000:更換它不會工作,因爲那將與:結束代替。此外,這將注意解析新添加的:導致:1050:0000::600:5:1000:0000:

那麼我需要這個正則表達式來做什麼?

更換每:通過:0000如果後面沒有

主要問題是數字或字母:::被替換,而不是1個:

+0

有[這](https://regex101.com/r/bW4xE0/1),但這不適用於Lua(我對任何可行的想法都是空白的)。 – Sam 2015-03-31 15:55:12

+0

Lua模式匹配不是標準的正則表達式。 – badcc 2015-03-31 21:29:33

回答

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

沒有單獨的語句模式要做到這一點,但你可以用一個函數來對任何可能的輸入做到這一點:

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