首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用LPeg匹配Unicode标点符号

使用LPeg匹配Unicode标点符号
EN

Stack Overflow用户
提问于 2016-08-17 21:44:27
回答 1查看 326关注 0票数 4

我正在尝试创建一个LPeg模式,以匹配UTF-8编码输入中的任何Unicode标点符号。我想出了Selene和LPeg的婚姻:

代码语言:javascript
复制
local unicode     = require("unicode")
local lpeg        = require("lpeg")
local punctuation = lpeg.Cmt(lpeg.Cs(any * any^-3), function(s,i,a)
  local match = unicode.utf8.match(a, "^%p")
  if match == nil
    return false
  else
    return i+#match
  end
end)

这似乎有效,但它将忽略由几个Unicode代码点组合而成的标点符号(如果存在这些字符),因为我前面只读取了4个字节,这可能会降低解析器的性能,而且当我将包含一个矮小UTF-8字符的字符串提供给它时,它可能会破坏解析器的性能,而且当我给它一个包含一个矮小的UTF-8字符的字符串时(尽管它现在似乎正常工作)。

我想知道这是否一种正确的做法,还是有更好的方法来实现我正在努力实现的目标。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-08-18 07:18:43

LPeg主页中的一个例子中显示了匹配UTF-8字符的正确方法。UTF-8字符的第一个字节决定了它的一部分还有多少字节:

代码语言:javascript
复制
local cont = lpeg.R("\128\191") -- continuation byte

local utf8 = lpeg.R("\0\127")
           + lpeg.R("\194\223") * cont
           + lpeg.R("\224\239") * cont * cont
           + lpeg.R("\240\244") * cont * cont * cont

在此utf8模式的基础上,我们可以使用lpeg.Cmt和Selene match函数,就像您建议的那样:

代码语言:javascript
复制
local punctuation = lpeg.Cmt(lpeg.C(utf8), function (s, i, c)
    if unicode.utf8.match(c, "%p") then
        return i
    end
end)

注意,我们返回i,这与Cmt所期望的是一致的:

给定的函数作为参数获取整个主题,当前位置(在patt匹配之后),以及patt生成的任何捕获值。函数返回的第一个值定义了匹配的发生方式。如果调用返回一个数字,则匹配成功,并且返回的号码将成为新的当前位置

这意味着我们应该返回函数接收的相同的数字,即在UTF-8字符之后的位置。

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

https://stackoverflow.com/questions/39006753

复制
相关文章

相似问题

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