Regex 在这个正则表达式中(^?)是什么意思?

Regex 在这个正则表达式中(^?)是什么意思?,regex,lua,Regex,Lua,我有一个正则表达式: ^(^?)*\?(.*)$ 如果我理解正确,这是它的功能的分解: ^-从字符串的开头开始匹配 (^?*)-我不知道,但它存储在1美元 \?-匹配一个问号 (.*)$-匹配任何内容,直到字符串结束 那么(^?)是什么意思?这个(^?只是在寻找文本字符^。正则表达式模式中的^字符仅当用作模式的第一个字符或分组匹配中的第一个字符时才具有特殊意义[]。当在这两个位置之外使用时,^在查找输入字符串中的^字符时按字面意义进行解释 注意:是否按字面解释第一个和分组位置之外的^,取决

我有一个正则表达式:

^(^?)*\?(.*)$
如果我理解正确,这是它的功能的分解:

  • ^-从字符串的开头开始匹配
  • (^?*)-我不知道,但它存储在1美元
  • \?-匹配一个问号
  • (.*)$-匹配任何内容,直到字符串结束
那么(^?)是什么意思?

这个
(^?
只是在寻找文本字符
^
。正则表达式模式中的
^
字符仅当用作模式的第一个字符或分组匹配中的第一个字符时才具有特殊意义
[]
。当在这两个位置之外使用时,
^
在查找输入字符串中的
^
字符时按字面意义进行解释

注意:是否按字面解释第一个和分组位置之外的
^
,取决于正则表达式引擎。我对LUA不太熟悉,无法说明它在做什么。在本例中,(^?)指的是前一个字符串“^”,意思是Jared所说的文字字符^。请查看regexlib以获得进一步的解密


对于您所有的正则表达式需求:

在我看来,表达式创建者的意图是匹配问号之前的任意数量的^,但只想捕获^的第一个实例。但是,根据引擎的不同,它可能不是一个有效的表达式,正如其他人所说。

Lua没有传统的regexp语言,它有Lua模式。虽然它们看起来很像regexp,但Lua模式本身是一种独特的语言,它有一组更简单的规则,最重要的是缺乏分组和交替特性

解释为Lua模式,这个例子会让长期使用regexp的用户感到惊讶,因为很多细节是不同的

Lua模式非常相似,乍一看与传统的regexp非常相似,会引起混淆。最大的区别可能是缺少交替运算符
|
,括号仅用于标记捕获,量词(
-
+
*
)仅适用于字符或字符类,
%
是转义字符,而不是
\
。这个示例可能不是用Lua编写的,一个重要的线索是缺少Lua模式引用字符
%
,该字符应用于模式字符串中的任何(或理想情况下,所有)非字母数字字符,还有可疑的
\?
用法,它闻起来像是一个传统的regexp来匹配单个文本

对所问问题的简单回答是:
(^?*
不是推荐的形式,它将匹配
^*
*
,捕获插入符号的存在或不存在。如果这是预期的效果,那么我会将其写为
(^?)%*
,以使其更清晰

要了解为什么会出现这种情况,让我们将给定的模式作为Lua模式进行分析。整个模式是:

^(^?)*\?(.*)$
交给
string.match()
,它的解释如下:

^
将匹配锚定到字符串的开头

标记第一次捕获的开始

^
不在模式或字符类的开头,因此它与文本
^
字符相匹配。为清楚起见,该字符可能被写成
%^

与前一个字符中的零个或一个完全匹配

标记第一次捕获的结束

*
不在可以量化的内容之后,因此它与文本
*
字符匹配。为清楚起见,本应写成
%*

\
在模式匹配自身时,它不是模式语言中的转义字符。但是,它是Lua短字符串文本中的转义字符,这使得以下字符对于字符串文本解析器不是特殊的,在本例中,字符串文本解析器是没有意义的,因为后面的
在任何情况下对它都不是特殊的。因此,如果模式用双引号或单引号括起来,那么
\
将被字符串解析吸收。如果用长字符串(如
[[^(^?*\?(.*)$])]
编写,反斜杠将在字符串解析器中保留下来,并显示在模式中

与前一个字符中的零个或一个完全匹配

标记第二次捕获的开始

完全匹配任何字符,实际上是类
[\000-\255]
的同义词(请记住,在Lua中,数字转义符是十进制的,而不是C中的八进制)

*
贪婪地匹配上一个字符的零个或多个

标记第二次捕获的结束

$
将模式锚定到字符串的末尾

因此,它在字符串开头匹配并捕获一个可选的
^
,然后是
*
,然后是一个未捕获的可选
\
,并捕获整个字符串的其余部分。
string.match
将在成功时返回两个字符串(其中一个或两个字符串的长度可能为零)出现故障时,或
nil

编辑:我修正了一些拼写错误,并纠正了我的答案中的一个错误,在评论中注意到。我忘记了在模式中,特殊符号在无法应用的地方会失去其特殊性。这使得第一个星号与文字星号匹配,而不是一个错误。这些星号的级联会贯穿大部分答案。

请注意,如果您真的想在Lua中使用真正的regexp,那么有一些库可以提供它。也就是说,内置模式语言非常强大。如果它不够强大,那么您最好采用完整的解析器,并使用它来完成regexp所能做的一切,甚至还可以使用