简体   繁体   English

Lua模式验证DNS地址

[英]Lua pattern to validate a DNS address

I am currently using this regular expression to loosely validate a DNS address: 我目前正在使用此正则表达式来松散地验证DNS地址:

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

Which would match things like hello.com , hello , and hello.com.com.com . 哪个匹配hello.comhellohello.com.com.com I was trying to replicate it exactly as it is into a Lua pattern. 我试图将它完全复制到Lua模式中。 I came up with the following Lua pattern: 我提出了以下Lua模式:

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

So that I can use the following code to validate the DNS address: 这样我就可以使用以下代码来验证DNS地址:

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

For some reason this always fails, although it looks like a 1:1 copy of the regular expression. 出于某种原因,这总是失败,虽然它看起来像正则表达式的1:1副本。

Any ideas why? 有什么想法吗?

Lua patterns are not regular expressions. Lua模式不是正则表达式。 You cannot translate the ^[A-Za-z0-9_]+(\\.[A-Za-z0-9_]+)*$ to ^([%d%a_]+(%.[%d%a_]+)*)$ , because you cannot apply quantifiers to groups in Lua (see Limitations of Lua patterns ). 你无法将^[A-Za-z0-9_]+(\\.[A-Za-z0-9_]+)*$^([%d%a_]+(%.[%d%a_]+)*)$ ,因为你不能将量词应用于Lua中的组(参见Lua模式的局限性 )。

Judging by the ^[A-Za-z0-9_]+(\\.[A-Za-z0-9_]+)*$ regex, the rules are: 通过^[A-Za-z0-9_]+(\\.[A-Za-z0-9_]+)*$ regex来判断,规则是:

  • String can consist of one or more alphanumeric or underscore or dot characters 字符串可以包含一个或多个字母数字或下划线或点字符
  • String cannot start with a dot 字符串不能以点开头
  • String cannot end with a dot 字符串不能以点结尾
  • String cannot contain 2 consecutive dots 字符串不能包含2个连续的点

You can use the following work-around: 您可以使用以下解决方法:

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

See IDEONE demo : 请参阅IDEONE演示

-- 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

You can translate the pattern to ^[%w_][%w_%.]+[%w_]$ , although that still allows for double dots. 您可以将模式转换为^[%w_][%w_%.]+[%w_]$ ,尽管这仍然允许双点。 When using that pattern while checking for double dots, you end up with this: 在检查双点时使用该模式时,最终会得到以下结果:

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

I used the same testcode as Wiktor Stribiżew (since it's good testcode) and it produces the same results. 我使用与WiktorStribiżew相同的测试Wiktor Stribiżew (因为它是很好的测试代码)并且它产生相同的结果。 Mine is also 2 to 3 times faster, if that matters. 如果重要的话,我的速度也快2到3倍。 (Doesn't mean I don't like Wiktor's code, his code also works. He also has a link to the limitations page, a nice touch to his answer) (并不意味着我不喜欢Wiktor的代码,他的代码也有效。他还有一个指向限制页面的链接,对他的答案很有帮助)

(I like playing with string patterns in Lua) (我喜欢在Lua中玩字符串模式)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM