首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用lpeg只捕获单词边界

使用lpeg只捕获单词边界
EN

Stack Overflow用户
提问于 2016-08-01 03:44:59
回答 2查看 269关注 0票数 2

我一直在使用文本编辑器来实现语法突出显示支持。启动和运行是相当简单的,但我只完成了最低要求。

我定义了一系列这样的模式:

代码语言:javascript
复制
 -- Keywords
 local keyword = C(
    P"auto" +
    P"break" +
    P"case" +
    P"char" + 
    P"int" 
    -- more ..
  ) / function() add_syntax( RED, ... )

这正确地处理输入,但不幸的是匹配太多。例如,intprintf中间进行匹配,这是预期的,因为我在文字匹配中使用"P“。

显然,为了执行“适当”的突出显示,我需要在单词边界上匹配,例如"int“匹配"int",而不是"printf","vsprintf”等等。

我试图用它来限制比赛只发生在"<[{ \n“之后,但这并没有达到我想要的效果:

代码语言:javascript
复制
  -- space, newline, comma, brackets followed by the keyword
  S(" \n(<{,")^1 * P"auto"  + 

这里是否有一个简单、明显的解决方案,只匹配被空格或C代码中所期望的其他字符包围的关键字/标记?我确实需要捕获的令牌,这样我就可以突出显示它,但否则我不会使用任何特定的方法。

例如,这些应与:

代码语言:javascript
复制
 int foo;
 void(int argc,std::list<int,int> ) { .. };

但这不应:

代码语言:javascript
复制
 fprintf(stderr, "blah.  patterns are hard\n");
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-04 12:54:28

LPeg sure -pattern (或者更具体地说是下面的示例中的-idchar )很好地确保了当前匹配没有跟随pattern (即idchar)。幸运的是,这也适用于输入末尾的空字符串,因此我们不需要对此进行特殊处理。为了确保匹配之前没有模式,LPeg提供了lpeg.B(pattern)。不幸的是,这需要一个匹配固定长度字符串的模式,因此在输入开始时不能工作。要解决以下代码在返回到检查字符串其余部分的后缀和前缀的模式之前,分别尝试在输入开头不使用lpeg.B()进行匹配的问题:

代码语言:javascript
复制
local L = require( "lpeg" )

local function decorate( word )
  -- highlighting in UNIX terminals
  return "\27[32;1m"..word.."\27[0m"
end

-- matches characters that may be part of an identifier
local idchar = L.R( "az", "AZ", "09" ) + L.P"_"
-- list of keywords to be highlighted
local keywords = L.C( L.P"in" +
                      L.P"for" )

local function highlight( s )
  local p = L.P{
    (L.V"nosuffix" + "") * (L.V"exactmatch" + 1)^0,
    nosuffix = (keywords / decorate) * -idchar,
    exactmatch = L.B( 1 - idchar ) * L.V"nosuffix",
  }
  return L.match( L.Cs( p ), s )
end

-- tests:
print( highlight"" )
print( highlight"hello world" )
print( highlight"in 0in int for  xfor for_ |for| in" )
票数 3
EN

Stack Overflow用户

发布于 2016-08-01 04:21:29

我认为您应该否定匹配模式,就像在文档的示例中那样

如果我们只想在字界寻找一个模式,我们可以使用以下转换器:

代码语言:javascript
复制
local t = lpeg.locale()
function atwordboundary (p)
  return lpeg.P{
    [1] = p + t.alpha^0 * (1 - t.alpha)^1 * lpeg.V(1)
  }
end

这个所以回答还讨论了一些类似的解决方案,因此可能会引起人们的兴趣。

还有一些另一个编辑器组件使用LPeg进行语法高亮化的解析,所以您可能想看看他们是如何处理这个问题的(或者,如果对您的设计有用的话,也可以使用它们的词汇)。

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

https://stackoverflow.com/questions/38690698

复制
相关文章

相似问题

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