egrep +量词不工作

时间:2016-08-19 19:42:16

标签: regex grep

egrep在以下示例中并不匹配,而是我应该阅读的所有内容。表达式为'{% +'我想要完成的是匹配我的降价文件中的所有{% %}括号。根据我目前的理解,它应该匹配{%然后匹配一个或多个空格,但如果没有空格则无法匹配。我可以在PowerShell中使用相同的表达式,但它匹配,所以我想知道它是什么,我错过了。

匹配的代码段
{% highlight ruby %}
{% endhighlight %}

cat file.md | egrep '{% +'

1 个答案:

答案 0 :(得分:1)

对我来说,你的正则表达式按预期工作。给定输入文件file.md包含:

{% highlight ruby %}
{% endhighlight %}
not this line, though
nor {%this%}

当我运行你的命令(避免UUoC)时,我得到了显示的输出:

$ egrep '{% +' file.md
{% highlight ruby %}
{% endhighlight %}
$

您尚未确定您使用的egrep版本以及您正在使用哪个版本的平台。我正在运行Mac OS X 10.11.6并使用egrep (BSD grep) 2.5.1-FreeBSD(但我也得到了与GNU Grep 2.25相同的结果)。

但是,您应该知道{egrep的元字符,问题可能是它没有像您期望的那样处理初始{

例如,这是一个更复杂的egrep调用,只能选择endhighlight行:

$ egrep '\{% {1,4}[a-z]{4,20} {1,4}%\}' file.md
{% endhighlight %}
$

我使用反斜杠来逃避第一个和最后一个括号。 {n,m}表示法意味着n≤x≤m匹配前面的正则表达式(空白和[a-z])。你可以省略,m;您也可以使用{4,} - 查看手册以了解这些内容。但是,在我的机器上,我也可以运行:

$ egrep '{% {1,4}[a-z]{4,20} {1,4}%}' file.md
{% endhighlight %}
$

据推测,因为第一个{没有启动{n,m}序列,所以它被视为普通字符。

如果你看一下Extended Regular Expressions的POSIX规范,你会发现它使用{这样就是未定义的行为:

  

*+?{

     

<asterisk><plus-sign><question-mark><left-brace>应该是特殊的,除非在括号表达式中使用(请参阅RE括号表达式)。以下任何一种用途都会产生不确定的结果:

     
      
  • 如果这些字符首先出现在ERE中,或者紧跟<vertical-line><circumflex><left-parenthesis>

  •   
  • 如果<left-brace>不是有效区间表达式的一部分(请参阅匹配多个字符的EREs)

  •   

因此,根据POSIX,您正在使用产生未定义结果的正则表达式。因此,您得到的结果是POSIX认为可以接受。

显然,您应该能够使用以下内容并获得您期望的结果:

$ egrep '\{% +' file.md
{% highlight ruby %}
{% endhighlight %}
$