Lua 验证 DNS 地址的模式
Lua pattern to validate a DNS address
我目前正在使用这个正则表达式来松散地验证 DNS 地址:
^[A-Za-z0-9_]+(\.[A-Za-z0-9_]+)*$
这将匹配 hello.com
、hello
和 hello.com.com.com
等内容。我试图将它原样复制到 Lua 模式中。我想出了以下 Lua 模式:
^([%d%a_]+(%.[%d%a_]+)*)$
以便我可以使用以下代码来验证 DNS 地址:
local s = "hello.com"
print(s:match("^([%d%a_]+(%.[%d%a_]+)*)$"))
出于某种原因,这总是失败,尽管它看起来像是正则表达式的 1:1 副本。
知道为什么吗?
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
您可以将模式转换为 ^[%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 的代码,他的代码也可以工作。他还有一个 link 到限制页面,对他的回答很好)
(我喜欢玩 Lua 中的字符串模式)
我目前正在使用这个正则表达式来松散地验证 DNS 地址:
^[A-Za-z0-9_]+(\.[A-Za-z0-9_]+)*$
这将匹配 hello.com
、hello
和 hello.com.com.com
等内容。我试图将它原样复制到 Lua 模式中。我想出了以下 Lua 模式:
^([%d%a_]+(%.[%d%a_]+)*)$
以便我可以使用以下代码来验证 DNS 地址:
local s = "hello.com"
print(s:match("^([%d%a_]+(%.[%d%a_]+)*)$"))
出于某种原因,这总是失败,尽管它看起来像是正则表达式的 1:1 副本。
知道为什么吗?
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
您可以将模式转换为 ^[%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 的代码,他的代码也可以工作。他还有一个 link 到限制页面,对他的回答很好)
(我喜欢玩 Lua 中的字符串模式)