首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LPeg模式,它与字符串没有连续的下线匹配

LPeg模式,它与字符串没有连续的下线匹配
EN

Stack Overflow用户
提问于 2016-10-22 08:31:40
回答 1查看 153关注 0票数 3

我正在尝试编写一个LPeg模式来匹配字符串,这些字符串:

  • 从一封信开始
  • 其后包含字母数字字符。
  • 不包含两个或多个连续连字符(例如,不允许test--string)

作为参考,正则表达式[a-zA-Z](-?[a-zA-Z0-9])*与我所寻找的匹配。

下面是我正在使用的代码,以供参考:

代码语言:javascript
复制
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

然而,令我沮丧的是,我得到了以下输出:

代码语言:javascript
复制
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--tt--t-tt--t不应该匹配。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-12-29 01:14:06

在您的模式letter * ((dash^-1) * alphanum)^0中,lpeg将尝试与字符串的前缀匹配。如果你没有预料到匹配的话

t--t t--t-t t--t

粗体突出显示的部分是您的模式成功匹配的地方。lpeg.match返回最后一个位置(这是一个数字),如果没有捕获任何信息,它就能够解析到使用您的模式。对于上述3种情况,将捕获匹配的子部分,从而解释您所看到的错误输出。

如果您只是一次只匹配每个字符串,则可以修改模式以检查解析后是否没有剩余的字符。

代码语言:javascript
复制
str_match = C(letter * ((dash^-1) * alphanum)^0) * -1

类似地使用lpeg.re模块

代码语言:javascript
复制
re_pat = re.compile "{ %a ('-'? %w)* } !."

对于流匹配或查找目标字符串中的所有模式,请将语法规则堆在一起,如下所示

代码语言:javascript
复制
stream_parse = re.compile
[[
  stream_match  <- ((str_match / skip_nonmatch) delim)* str_match?
  str_match     <- { %a ('-'? %w)* } (&delim / !.)
  skip_nonmatch <- !str_match (!delim .)*

  delim         <- %s+
]]

任何火柴都会被捕获并归还。如果没有匹配,您将返回nil或指示字符串中模式停止解析的位置的数字。

编辑:对于需要解析来返回不匹配的nil的情况,对语法的调整应该能做到这一点

代码语言:javascript
复制
stream_parse = re.compile
[[
  stream_match  <- (str_match / skip_nonmatch+ &str_match)+
  str_match     <- { %a ('-'? %w)* } (&delim / !.)
  skip_nonmatch <- !str_match (!delim .)* delim

  delim         <- %s+
]]
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40189994

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档