第6.4.1节“ Lua模式”中的Lua manual
字符类用于表示一组字符。的 描述字符类时,允许以下组合:
x
:(其中x
不是魔术字符^$()%.[]*+-?
之一)表示字符x本身。.
:(一个点)代表所有字符。%a
:代表所有字母。%c
:代表所有控制字符。%d
:代表所有数字。%g
:代表除空格以外的所有可打印字符。%l
:代表所有小写字母。%p
:代表所有标点符号。%s
:代表所有空格字符。%u
:代表所有大写字母。%w
:代表所有字母数字字符。%x
:代表所有十六进制数字。%
x :(其中x是任何非字母数字字符)表示字符x。这是逃脱魔术角色的标准方法。 任何非字母数字字符(包括所有标点字符, 即使是非魔法的)也可以在表示之前用%
开头 本身以一种模式。[set]
:表示该类,它是set
中所有字符的并集。可以通过分隔结尾指定字符范围 范围内的字符,以-
升序排列。所有课程 上述%x
也可以用作集合中的组件。所有其他set
中的字符代表自己。例如,[%w_]
(或[_%w]
)代表所有字母数字字符以及下划线,[0-7]
代表八进制数字,[0-7%l%-]
代表八进制数字 八进制数字加上小写字母再加上-
字符。您可以将封闭的方括号放置在集合中,方法是将其放置在 集合中的第一个字符。您可以将连字号放在 将其定位为集合中的第一个或最后一个字符。 (您可以 两种情况也都使用转义符。)
范围和类之间的交互未定义。因此,[%a-z]或[a-%%]之类的模式没有意义。
[^set]
:表示集合的补码,其中解释集合 如上所述。对于用单个字母表示的所有类(
%a
,%c
等), 相应的大写字母表示该类的补语。 例如,%S代表所有非空格字符。字母,空格和其他字符组的定义取决于 当前语言环境。特别是,类
[a-z]
可能不是 等效于%l
。
(突出显示和我添加的某些格式)
因此,由于“未定义范围和类之间的交互。” ,如何创建以(魔术)字符开头和/或结束的字符类set
需要逃脱?
例如
[%%-c]
不定义从%
到c
的字符类,并且不包括中间的所有字符,而是只包含三个字符%
,{{1}的字符集}和-
。
答案 0 :(得分:1)
范围和类之间的交互未定义。
很显然,这不是一个固定的规则(通常是正则表达式字符集),而是一个Lua实现的决定。在字符集/范围中使用速记字符可以以某些(大多数)正则表达式形式使用,但不能全部使用(例如在Python的re模块demo中)。
但是,第二个示例具有误导性:
因此,[%a-z]或[a-%%]之类的模式没有意义。
虽然第一个示例很好,因为%a
是set
中的速记类(代表所有字母),但[%a-z]
是未定义的,如果匹配则返回nil
反对一个字符串。
[set]
中的转义范围字符在第二个示例中,[a-%%]
,%%
仅定义了转义的%符号,而不是速记字符类。肤浅的问题是,上下颠倒的范围是从高到低(参考字符的US ASCII值) a
61 和{{1} 37 ),例如像%
这样的错误Lua模式。如果以相反的顺序定义了集合,则它seems to work:[f-a]
,但是它所做的只是匹配三个单独的字符,而不是匹配[%%-a]
和%
之间的字符范围;信用cyclaminist)。
这可能被认为是一个错误,实际上,这意味着如果需要转义一个定义范围字符,则无法在a
中创建字符范围。
从不需要转义的下一个字符开始字符范围-然后分别添加其余的转义字符,例如
[set]
[%%&-a]
这是我找到的答案。不过,也许其他人有更好的东西。