【发布时间】:2017-03-04 13:16:17
【问题描述】:
我正在尝试编写一个 LPeg 模式来匹配以下字符串:
- 以字母开头
- 之后包含字母数字字符
- 不包含两个或多个连续的连字符(例如不允许
test--string)
作为参考,正则表达式 [a-zA-Z](-?[a-zA-Z0-9])* 匹配我要查找的内容。
这是我正在使用的代码,供参考:
require "lpeg"
P,R,C = lpeg.P,lpeg.R,lpeg.C
dash = P"-"
ucase = R"AZ"
lcase = R"az"
digit = R"09"
letter = ucase + lcase
alphanum = letter + digit
str_match = C(letter * ((dash^-1) * alphanum)^0)
strs = {
"1too",
"too0",
"t-t-t",
"t-t--t",
"t--t-t",
"t-1-t",
"t--t",
"t-one1",
"1-1",
"t-1",
"t",
"tt",
"t1",
"1",
}
for _,v in ipairs(strs) do
if lpeg.match(str_match,v) ~= nil then
print(v," => match!")
else
print(v," => no match")
end
end
然而,令我沮丧的是,我得到以下输出:
1too => no match
too0 => match!
t-t-t => match!
t-t--t => match!
t--t-t => match!
t-1-t => match!
t--t => match!
t-one1 => match!
1-1 => no match
t-1 => match!
t => match!
tt => match!
t1 => match!
1 => no match
尽管代码输出了什么,t-t--t、t--t-t 和 t--t 不应该匹配。
【问题讨论】:
-
仔细看看
((dash^-1) * alphanum)^0!您说“将最多一个破折号后面紧跟一个字母数字的可能性分组,这一切都可能发生 0 次或更多次。”。因此,您的模式可能会在开头字母处失败。