Lua模式验证DNS地址

我目前正在使用这个正则表达式来粗略验证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_]+)*)$"))

出于某种原因,它总是失败,尽管它看起来像是对正则表达式的精确复制。

有什么想法吗?

点赞
用户3832970
用户3832970

Lua patterns 不是正则表达式。你不能将 ^[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 -- 检查字符串是否仅包含数字/字母/_/./,一个或多个
           string.sub(v, 0, 1) ~= '.' and            -- 检查第一个字符是否不是'.'
           string.sub(v, -1) ~= '.' and              -- 检查最后一个字符是否不是'.'
           string.find(v, '%.%.') == nil             -- 检查字符串中是否有 2 个连续的点
end

参见 IDEONE demo

-- 正确的示例
print(pattern_checker("hello.com")) -- true
print(pattern_checker("hello")) -- true
print(pattern_checker("hello.com.com.com")) -- true
-- 错误的示例
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
2016-02-17 22:36:24
用户5352026
用户5352026

你可以将模式转换为 ^[%w_][%w_%.]+[%w_] $,但仍允许双点号的存在。当使用该模式检查双点号时,你最终得到如下代码:

function pattern_checker(v)
    -- 使用双“not”因为我们喜欢布尔值,对吧?
    return not v:find(“..”,1trueand not not v:match("^[%w_][%w_%.]+[%w_]$")
end

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

(我喜欢在Lua中玩弄字符串模式)

2016-02-18 09:05:50