我不知道这个正则表达式在 Lex 中是如何工作的:
1) \"([^\\\"]|\\\n|\\.)*\"
第一个表达式捕获这样的条目 :"one"
或"test"
. 也就是说,双引号中的单词。以下是我对第一个正则表达式的了解:
\" - экранирование спец. символа кавычка
(что-то в скобках)* - звёздочка означает любое (в том числе и 0) число вхождений символа
然后括号里面是|
,表示или
,即[^\\\"]
要么 要么\\\n
被选中\\.
我试图弄清楚[^\\\"]
这些是什么\\\n
意思\\.
。
我将从 [^\\\"]
. 方括号中的抑扬符(^)表示如果字符不相等则选择任何字符串\ или "
(我看到斜线转义和引号转义)。
然后 or 符号后跟\\\n
。在这里,我再次看到斜线字符的转义和到新行的过渡。
然后 -\\.
转义点(根据定义,点接受除 \n 之外的任何字符)。也就是模板要找字符\.
问题:以上所有内容如何帮助捕捉像"one"
or之类的词"test"
?我是否正确识别每个条目的含义?尚不清楚为什么有\\\n
必要\\.
这是一个匹配双引号中的字符串的正则表达式,根据许多编程语言的规则编写,例如,C和C++、Javascript、JSON、C#、Java(虽然其中一些没有换行的能力)。
它是如何工作的?
引号中可以包含什么?一个常规字符或用反斜杠转义的东西。但是斜线本身也可以被另一个斜线转义。我们不能只是处理
\\
,因为情况对我们来说\\\"
也\\\\"
完全不同——第二个结束,而第一个没有。所以在处理转义斜线时,我们需要确切知道它转义的是什么。所以在第一个分支中,我们采用普通字符——除了引号(它结束行)和反斜杠之外的所有字符——它肯定会转义一些东西。现在,对于其余的分支,我们知道它们以斜杠开头(引号结束字符串 - 无需对其进行任何操作)。所以我们要处理不同版本的转义。首先,\0
,\7
,\07
,\x20
,\u0020
,\u{1f60b}
,\\
,\n
,\t
和其他的,还有一些语言允许在任何字符之前转义。其次,直接换行。从理论上讲,我们应该列出所有这些选项,但如果我们更仔细地观察它们,就会发现只有对我们来说是危险的\\
,其余的可以沿着主分支 - 那里没有第二个斜线。因此,我们稍微简化了表达式,并说\
任何字符都可以跟在后面(正好被斜线转义),如果斜线转义更长的序列,那么主分支会处理它——这对我们来说是安全的。为什么至少需要吃一个角色?这样在回滚时,搜索算法就不能分成\\
两次出现\
. 好吧,为什么要单独换行-您自己说-它在点上不匹配。确实,取决于语言、操作系统和获取行的方法,从 中出现换行符\r\n
,而不仅仅是一个可能会在其中弹出\n
- 我不确定这种情况是否由正则表达式处理 - 它可能是值得添加一个选项,该选项可能还取决于第一个分支与换行符的匹配,但您可以编写更通用的\\\r?\n
. 好吧,如果我们解析 php.ini 之类的内容,您可能希望在第一个分支中添加一个干净的换行符。PS:而且常规赛中的报价本身,理论上是不需要转义的。这显然不是来自字符串的正则表达式,因为字符串中需要更多的转义(你好 Java)。虽然我不明白它写在哪里,但也许那里确实有必要。
此表达式查找三种类型的带引号的字符串:
第一种选择:任何不包含
\
.第二种选择:在第一行以新行的形式添加内部有中断的行,之前有
\
第三种选择:在第一行添加带有任何字符的斜线的行。
在我看来,之前有额外的转义
"
(或者这是 lex 的一个特性)。至少https://regex101.com/不接受它们,符号本身"
也没有特殊含义。在第三种选择中,不是一个点被转义,而是一个斜线。如果您不考虑 2 和 3 的简单情况,当它们返回自己时,如果前面有斜杠,则 2 添加一个中断,3 用斜杠转义任何一个字符,所有这些都在找到 1 的字符串中.
对于 3,我也会做一个集合,例如,
["\\]
是的,对于搜索“一个”,“测试”就足够了
\"([^\\\"])*\"
。