Lua模式验证DNS地址

时间:2016-02-17 21:02:00

标签: regex lua dns lua-patterns

我目前正在使用此正则表达式来松散地验证DNS地址:

^[A-Za-z0-9_]+(\.[A-Za-z0-9_]+)*$

哪个匹配hello.comhellohello.com.com.com等内容。我试图将它完全复制到Lua模式中。我提出了以下Lua模式:

^([%d%a_]+(%.[%d%a_]+)*)$

这样我就可以使用以下代码验证DNS地址:

local s = "hello.com"
print(s:match("^([%d%a_]+(%.[%d%a_]+)*)$"))

出于某种原因,这总是失败,尽管它看起来像正则表达式的1:1副本。

任何想法为什么?

2 个答案:

答案 0 :(得分:6)

Lua模式不是正则表达式。您无法将^[A-Za-z0-9_]+(\.[A-Za-z0-9_]+)*$翻译为^([%d%a_]+(%.[%d%a_]+)*)$,因为您无法将量词应用于Lua中的组(请参阅Limitations of Lua patterns)。

根据^[A-Za-z0-9_]+(\.[A-Za-z0-9_]+)*$正则表达式判断,规则是:

  • 字符串可以包含一个或多个字母数字或下划线或点字符
  • 字符串不能以点开头
  • 字符串不能以点结尾
  • 字符串不能包含2个连续的点

您可以使用以下解决方法:

function pattern_checker(v)
    return string.match(v, '^[%d%a_.]+$') ~= nil and -- check if the string only contains digits/letters/_/., one or more
           string.sub(v, 0, 1) ~= '.' and            -- check if the first char is not '.'
           string.sub(v, -1) ~= '.' and              -- check if the last char is not '.'
           string.find(v, '%.%.') == nil             -- check if there are 2 consecutive dots in the string
end

请参阅IDEONE demo

-- good examples
print(pattern_checker("hello.com")) -- true
print(pattern_checker("hello")) -- true
print(pattern_checker("hello.com.com.com")) -- true
-- bad examples
print(pattern_checker("hello.com.")) -- false
print(pattern_checker(".hello")) -- false
print(pattern_checker("hello..com.com.com")) -- false
print(pattern_checker("%hello.com.com.com")) -- false

答案 1 :(得分:1)

您可以将模式转换为^[%w_][%w_%.]+[%w_]$,但仍允许双点。在检查双点时使用该模式时,最终会得到:

function pattern_checker(v)
    -- Using double "not" because we like booleans, no?
    return not v:find("..",1,true) and not not v:match("^[%w_][%w_%.]+[%w_]$")
end

我使用与Wiktor Stribiżew 相同的测试代码(因为它是一个很好的测试代码),它会产生相同的结果。如果重要的话,我的速度也快2到3倍。 (并不意味着我不喜欢Wiktor的代码,他的代码也有效。他还有一个指向限制页面的链接,对他的答案很有帮助)

(我喜欢在Lua中使用字符串模式)