我正在试图弄清楚我在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方法进行比较时的结果只匹配字符串,只有两个星号后跟一个空格。
当^ -character前面加一个反斜杠时,第一个星号是一个文字星号,反斜杠 - *代表'前面字符的零个或多个'。
带有初始反斜杠的版本为我提供了我想要的答案;即,它匹配以一个或多个星号开头,后跟空格的所有和唯一的行。为什么是这样?当我查看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)
答案 0 :(得分:4)
啊,有趣的解释,但不是很正确。
\^
确实是指字面上的旋律。
但是*
并不意味着“一个或更多”,它意味着“零或更多”,因此\^*
根本不匹配任何内容如果它需要为了使表达的其余部分成功,此外它显然将“deanchor”搜索的其余部分,使其更容易成功。
我想,通过填充这一块拼图,您将毫不费力地理解其余部分......
更新:我认为最后一个难题是vi与上下文正则表达式魔术角色有所不同。如果你在一个不可能是神奇的环境中使用它,你将不会得到像Perl或Ruby那样的错误,这个角色变得非魔法。并且*
不会重复^
锚点,因此/*/
或/^*/
之类的搜索会查找任何实际*
或以实际开头的行分别为*
。
答案 1 :(得分:2)
'\^*\*\s'
匹配,因为第一个星号表示零或更多 ^
(在这种情况下为零),然后下一个文字*
与第一个匹配发生。
答案 2 :(得分:2)
为什么不简单地使用:'^\*\+
'?这将匹配VIM中行开头的一个或多个星号。