在 Lua 模式中使用转义(魔法)字符作为字符范围的边界

Lua 手册的 6.4.1 节中介绍了 Lua 模式,其中标明:

用于表示字符集的是字符类。在描述字符类时允许以下组合:

  • x:其中 x 不是 ^ $() %. [] *+ -? 这些魔法字符之一,则代表字符 x 本身。
  • .:(一个句点)代表所有字符。
  • %a:代表所有字母。
  • %c:代表所有控制字符。
  • %d:代表所有数字。
  • %g:代表所有可打印字符(除空格外)。
  • %l:代表所有小写字母。
  • %p:代表所有标点符号字符。
  • %s:代表所有空白字符。
  • %u:代表所有大写字母。
  • %w:代表所有字母数字字符。
  • %x:代表所有十六进制数字。
  • % x:(其中 x 是任意一个非字母数字字符)代表字符 x。 这是转义魔法字符的标准方法。 任何非字母数字字符(包括所有标点符号字符,甚至非魔法的)在模式中表示其本身时,均需在模式中使用 %
  • [集合]:代表集合中所有字符的并集。可以通过用 - 将范围的结束字符升序分隔来指定一组字符的范围。所有上述 %x 类也可以在集合中作为组件使用。 集合中其他所有字符均代表它们自己。例如,[%w_](或 [_%w])代表所有字母数字字符加下划线,[0-7] 代表八进制数字,[0-7%l%-] 代表八进制数字加小写字母加 - 字符。

可以通过将闭合方括号置于集合中的第一个字符位置来在集合中放置闭合方括号。 可以通过将连字符置于集合中的第一个或最后一个字符位置来放置连字符。(两种情况均可以使用转义。)

范围和类别之间的交互未定义。 因此,像 [%a-z] 或 [a-%%] 这样的模式没有意义。

[^集合]:代表集合取反,其中集合的解释如上所述。

对于所有由单个字母(%a%c 等)表示的类别,相应的大写字母表示类别的补集。 例如,%S 代表所有非空白字符。

字母、空格和其他字符组的定义取决于当前区域设置。 特别是,类别 [a-z] 可能与 %l 不等同。

(高亮显示和一些格式由我添加)

因此,既然 _"范围和类别之间的交互未定义。"_,那么如何创建以需要转义的(魔法)字符开头和/或结尾的字符类 set

例如,

[%%-c] 

并不定义一个从 %c 的范围并包括中间的所有字符,而是仅限于包括三个字符 %-c 的集合。

原文链接 https://stackoverflow.com/questions/53234492

点赞
stackoverflow用户8291949
stackoverflow用户8291949

[set]中的转义字符范围

在第二个例子中,[a-%%]中的%%仅仅表示一个转义符号,而不是简写的字符类。这个表面上的问题是,范围是上下颠倒的,从高位低位进行定义(参考字符 a _61_和 % _37_的US ASCII 值),例如像 Lua 模式的误用,如 [f-a]。如果将集合定义在相反的顺序中,它看起来可以工作[%%-a] ,但它所做的只是匹配这三个单独的字符,而不是介于 %a 之间的字符范围。(感谢 cyclaminist)。这可能被认为是一个 bug,确实意味着在 [set] 中创建一个字符范围是不可能的,如果其中一个定义范围字符需要被转义。

可能的解决方法

从不需要被转义的下一个字符开始字符范围,然后单独添加其余需要转义的字符,例如

[%%&-a]

示例

for w in string.gmatch("%&*()-0Aa", "[%%&-a]") do
  print(w)
end

这是我找到的答案。但是,也许还有人有更好的方法。

2018-11-09 23:36:15