关于 Vim 中正则表达式的问题

Her*_*itz 5 regex vim

我试图找出 Vim 中得到的一些正则表达式比较结果背后的原因。我正在尝试匹配以一个或多个星号开头的字符串。以下是各种正则表达式如何匹配字符串:

echo '* text is here' =~ '\^*\*\s'  prints 1 (i.e., MATCH)
echo '* text is here' =~ '^*\*\s'   prints 0 (NO MATCH)

echo '** text is here' =~ '\^*\*\s' (MATCH)
echo '** text is here' =~ '^*\*\s'  (MATCH)

echo '*** text is here' =~ '\^*\*\s' (MATCH)
echo '*** text is here' =~ '^*\*\s'  (NO MATCH)

echo 'text is here' =~ '\^*\*\s' (NO MATCH)
echo 'text is here' =~ '^*\*\s'  (NO MATCH)

echo '*text is here' =~ '\^*\*\s' (NO MATCH)
echo '*text is here' =~ '^*\*\s'  (NO MATCH)
Run Code Online (Sandbox Code Playgroud)

从这些结果中,我得出结论,当行字符的开头 (^) 前面没有反斜杠时,后面的 * 将被读取为文字反斜杠_* 也将被读取为文字。因此,使用 no-initial-backslash 方法进行比较时的结果仅匹配恰好有两个星号后跟一个空格的字符串。

当 ^ 字符前面带有反斜杠时,第一个星号是字面星号,反斜杠-* 代表“零个或多个前面的字符”。

带有初始反斜杠的版本给了我我想要的答案;即,它匹配以一个或多个星号开头,后跟一个空格的所有且唯一的行。为什么是这样?当我查看 Vim 文档时,它说 \^ 代表文字 ^,而不是行的开头。我确信有一个简单的解释,但我看不到。感谢您的任何澄清。

在输入这个问题时,我还注意到一些类似的行为。也就是说,以下字符串在文本中未显示的第二个星号之前有一个反斜杠: '^**\s​​' 。

更新:好的,我想我已经理解了罗斯的答案,并且发现解除锚定给了我想要的结果。解除锚定也给了我一个我不想要的结果,即:

echo 'text* is here' =~ '\^*\*\s' (MATCH)
Run Code Online (Sandbox Code Playgroud)

所以我现在的问题是:什么正则表达式将匹配以一个或多个星号开头并后跟空格的所有且唯一的行?下面的正则表达式很接近,但在最后一个示例中失败了:

echo '*** text is here' =~ '^**\s' (MATCH)
echo '* text is here' =~ '^**\s' (MATCH)
echo 'text* is here' =~ '^**\s' (NO MATCH)
echo ' * text is here' =~ '^**\s' (MATCH) -- want a no match here
Run Code Online (Sandbox Code Playgroud)

以斜杠星号作为第一个星号的版本也不起作用(即 '^\**\s' )。

最终更新:好的,我想我找到了有效的版本。但我不明白它为什么有效。它看起来像我所期望的,除了 ^ 字符后面的星号之外,但是在 ^ 后面有一个中继器似乎是无意义的:

echo '*** text is here' =~ '^*\**\s' (MATCH)
echo '* text is here' =~ '^*\**\s'   (MATCH)
echo 'text* is here' =~ '^*\**\s'   (NO MATCH)
echo ' * text is here' =~ '^*\**\s' (NO MATCH)
Run Code Online (Sandbox Code Playgroud)

Dig*_*oss 4

啊,有趣的解释,但不太正确。

确实\^指的是字面的抑扬符。

*并不意味着“一个或多个”,它意味着“零个或多个”,因此\^*如果需要的话,只需简单地匹配任何内容,以使表达式的其余部分成功,此外,它显然会“解除”其余部分搜索使其更容易成功。

我想,填满这块拼图后,您将毫无困难地理解其余部分......

更新:我认为最后一个难题是 vi 对脱离上下文的正则表达式魔术字符做了一些不同的事情。如果您在无法使用魔法的上下文中使用它,则不会像使用 Perl 或 Ruby 那样出现错误,该字符只是变得非魔法。并且*不重复锚点,因此像或^这样的搜索将分别查找任何实际的或以实际 开头的行。/*//^*/**