我有这个正则表达式:
^(^?)*\?(.*)$
如果我理解正确,这就是它的作用细分:
那么(^?)*是什么意思?
答案 0 :(得分:21)
(^?)
只是寻找文字字符^
。当用作模式的第一个字符或分组匹配^
中的第一个字符时,正则表达式模式中的[]
字符仅具有特殊含义。在这2个位置之外使用时,^
在字面上的解释意味着在输入字符串中查找^
字符
注意:第一个和分组位置之外的^
是否按字面解释是特定于正则表达式引擎。我对LUA不太熟悉,不知道它做了什么
答案 1 :(得分:7)
Lua没有传统的正则表达式语言,它有Lua模式。虽然它们看起来很像regexp,但是Lua模式是他们自己的一种独特的语言,它有一套更简单的规则,最重要的是缺乏分组和交替功能。
解释为Lua模式,该示例将令长期regexp用户感到惊讶,因为许多细节都不同。
Lua模式为described in PiL,乍一看与常规正则表达式相似,会造成混淆。最大的差异可能是缺少交替运算符|
,括号仅用于标记捕获,量词(?
,-
,+
和{{1} })仅适用于字符或字符类,*
是转义字符而不是%
。这个例子可能不是用Lua编写的一个很大的线索是缺少Lua模式引用字符\
应用于模式字符串中的任何(或理想情况下全部)非字母数字字符,以及怀疑使用%
,闻起来像传统的正则表达式,以匹配单个文字\?
。
问题的简单答案是:?
不是推荐的表单,并且会匹配(^?)*
或^*
,以捕获插入符的存在与否。如果这是预期的效果,那么我会将其写为*
以使其更清晰。
要了解为什么会这样,让我们采用给定的模式并将其分析为Lua模式。整个模式是:
(%^?)%*
传递给^(^?)*\?(.*)$
,它将被解释如下:
string.match()
将匹配锚定在字符串的开头。
^
标志着第一次捕获的开始。
(
不在模式的开头或字符类,因此它与文字^
字符匹配。为清楚起见,应该写成^
。
%^
完全匹配前一个字符的零或一个。
?
标志着第一次捕获的结束。
)
不是可以量化的东西,因此它匹配文字*
字符。为清楚起见,应该写成*
。
%*
与自身匹配,它不是模式语言中的转义字符。但是,是 Lua短字符串文字中的转义字符,使得后面的字符对于字符串文字解析器不是特殊的,在这种情况下,因为后面的\
不是特别的无论如何。因此,如果模式用双引号或单引号括起来,那么?
将被字符串解析所吸收。如果用长字符串(\
)编写,反斜杠将在字符串解析器中存活,以显示在模式中。
[[^(^?)*\?(.*)$]]
完全匹配前一个字符的零或一个。
?
标志着第二次捕获的开始。
(
匹配任何字符,实际上是类.
的同义词(请记住,在Lua中,数字转义符为十进制,而不是C中的八进制)。
[\000-\255]
贪婪地匹配前一个字符的零个或多个。
*
标志着第二次捕获的结束。
)
将模式锚定到字符串的末尾。
因此,它匹配并在字符串的开头捕获可选的$
,然后是^
,然后是未捕获的可选*
,并捕获整个其余部分串。成功时\
会返回两个字符串(其中一个或两个字符串可能为零长度),或者string.match
失败时返回。{/ p>
修改:我修正了一些拼写错误,并更正了我的回答中的错误,Egor在评论中注意到了该错误。我忘了在模式中,特殊符号在不能应用的地方失去了它们的特殊性。这使得第一个星号匹配文字星号而不是错误。大部分答案都属于这种级联。
请注意,如果你真的想在Lua中使用真正的正则表达式,那么可以使用它来提供它。也就是说,内置的模式语言非常强大。如果还不够,那么你可能最好采用一个完整的解析器,并使用LPeg,它可以完成regexp所能做的所有事情。它甚至带有一个模块,提供完整的正则表达式语法,该语法被翻译成LPeg语法以供执行。
答案 2 :(得分:2)
在这种情况下,(^?)引用前一个字符串“^”,表示Jared所说的文字字符^。检查regexlib是否有任何进一步的解密。
满足您的所有正则表达式需求:http://regexlib.com/CheatSheet.aspx
答案 3 :(得分:1)
在我看来,表达式的创建者的意图是在问号之前匹配任意数量的^,但只想捕获 ^的第一个实例。但是,根据引擎的不同,它可能不是一个有效的表达,正如其他人所说的那样。