【问题标题】:question about regex in Vim关于 Vim 中正则表达式的问题
【发布时间】:2010-09-06 01:02:06
【问题描述】:

我试图找出我在 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)

从这些结果中,我推测当行首字符 (^) 未在 前加上反斜杠时,以下 * 被读取为文字 并且 反斜杠_*也被读作文字。因此,使用 no-initial-backslash 方法进行比较时的结果仅匹配正好有两个星号后跟一个空格的字符串。

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

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

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

更新:好的,我想我已经理解了罗斯的回答,并且看到去锚定给了我想要的结果。解锚也给了我一个我不想要的结果,即:

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' (MATCH) -- want a no match here

斜线星号作为第一个星号的版本也不起作用(即 '^\**\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)

【问题讨论】:

    标签: regex vim


    【解决方案1】:

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

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

    但是* 并不意味着“一个或更多”,它意味着“或更多”,所以\^* 只是在需要时不匹配任何内容为了使表达式的其余部分成功,此外它显然会“解锚”其余的搜索,使其更容易成功。

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

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

    【讨论】:

    • Ross -- 谢谢,但我还是不太明白。我提到的“一个或多个”只是一个错字。我知道 * 表示“零或多个”(但实际上在默认的 vim 正则表达式中,* 转发器应该没有初始反斜杠)。但是我仍然无法弄清楚您的解释,因为带有反斜杠开头的版本与以星号以外的其他内容开头的字符串不匹配。我添加了其他示例来说明这一点。
    【解决方案2】:

    '\^*\*\s' 匹配,因为第一个星号表示零或多个 ^(在本例中为零),然后下一个文字 * 匹配第一个匹配项。

    【讨论】:

      【解决方案3】:

      为什么不简单地使用:'^\*\+'?这将匹配 VIM 中行首的一个或多个星号。

      【讨论】:

      • 谢谢。这正是我想要的。开始使用 * 中继器走错方向,没想到要切换方法。
      猜你喜欢
      • 2019-08-27
      • 1970-01-01
      • 2011-08-27
      • 1970-01-01
      • 2017-01-15
      • 2012-11-23
      • 1970-01-01
      • 2011-11-14
      • 1970-01-01
      相关资源
      最近更新 更多