我如何与GREP中的正面括号匹配方括号

  • 本文关键字:方括号 GREP regex bash grep
  • 更新时间 :
  • 英文 :


我试图将[]与GREP匹配,但仅成功地匹配[。无论我如何尝试,我似乎都无法正确匹配]

这是一个代码样本:

echo "fdsl[]" | grep -o "[ a-z]+" #this prints fdsl
echo "fdsl[]" | grep -o "[ [a-z]+" #this prints fdsl[
echo "fdsl[]" | grep -o "[ ]a-z]+" #this prints nothing
echo "fdsl[]" | grep -o "[ []a-z]+" #this prints nothing

编辑:我需要这样做的我的原始正则是:

echo "fdsl[]" | grep -o "[ []tna-zA-Z/:.0-9_~"'+,;*=()$!@#&?-]+" 
#this prints nothing

n.B:我已经尝试了这篇文章中的所有答案,但这在此特定情况下无效。我需要在[]中使用这些括号。

根据bre/erere括号的表达式部分,POSIX REGEX规范:

  1. [...]右支架(']')应失去其特殊含义,如果在列表中首先发生(在初始绕行后('^')(如果有)),则在括号表达式中表示自己。否则,它应终止括号表达式,除非它出现在整理符号(例如"[.].]")中,或者是整理符号,等效类或字符类的结尾右支架。特殊字符 '.''*''['''(分别为星号,左支架和后斜线)在括号表达式中应失去其特殊含义。

  1. [...]如果括号表达式指定'-'']',则应首先放置']'(如果有的话,'^'之后)和'-'在支架表达式内持续。

因此,您的正则应为:

echo "fdsl[]" | grep -Eo "[][ a-z]+"

请注意E标志,该标志指定使用ERE,该标志支持+量词。+量词不支持BRE(默认模式)。

Mike Holt的答案中的解决方案"[][a-z ]+"具有ESC_22的 +起作用,因为它在GNU GREP上运行,该gnu grep将语法扩展以支持+以表示重复一次或多个。根据POSIX标准,它实际上是未定义的行为(这意味着实现可以给出有意义的行为并记录下来,或者抛出语法错误或其他任何内容)。

如果您可以假设您的代码只能在GNU环境上运行,那么使用Mike Holt的答案是完全可以的。以sed为例,当您使用POSIX sed(无标志可以切换到ERE)时,您会陷入BRE,并且使用Posix BRE编写简单的正则表达式很麻烦,其中唯一定义的量词是*

原始正则

请注意,grep逐行消耗输入文件,然后检查该行是否匹配正则条件。因此,即使您在原始正则义务中使用P标志,n也总是多余的,因为正则条件不能跨线匹配。

虽然可以匹配水平选项卡没有 P标志,但我认为在此任务中使用P标志更自然。

给定此输入:

$ echo -e "fdstl[]kSAJD<>?,./:";'{}|[]\!@#$%^&*()_+-=~`89"
fds     l[]kSAJD<>?,./:";'{}|[]!@#$%^&*()_+-=~`89

问题中的原始正则态度几乎没有修改(末尾 +):

$ echo -e "fdstl[]kSAJD<>?,./:";'{}|[]\!@#$%^&*()_+-=~`89" | grep -Po "[ []tna-zA-Z/:.0-9_~"'+,;*=()$!@#&?-]+"
fds     l[]kSAJD
?,./:";'
[]
!@#$
&*()_+-=~
89

尽管我们可以删除n(如上所述,因为它是多余的),还有其他一些不必要的逃逸:

$ echo -e "fdstl[]kSAJD<>?,./:";'{}|[]\!@#$%^&*()_+-=~`89" | grep -Po "[ []ta-zA-Z/:.0-9_~"'+,;*=()$!@#&?-]+"
fds     l[]kSAJD
?,./:";'
[]
!@#$
&*()_+-=~
89

一个问题是 [是表达中的特殊字符,它不能被 逃脱(至少在我的grep口味中)。解决方案是将其定义为[[]

根据常规expressions.info:

在大多数正则口味中,角色类中唯一的特殊字符或元谱是闭合括号(]),后斜线(),caret(^)和连字符( - )( - )。通常的metacharacters是字符类中的普通字符,不需要被后斜切逃脱。

...和...

可以通过用后斜切逃脱,或将它们放置在不具有特殊含义的位置中来包括闭合支架(]),car(^)和连字符( - )。p>因此,假设grep支持的正则表达式语法的特定风味符合此符合此功能,那么我本来可以预期"[ a-z[]]+" 应该

但是,我的GREP版本(GNU GREP 2.14)仅在"fdsl[]"末尾与"[]"匹配此正则是。

但是,我尝试使用该报价中提到的其他技术(将]放置在角色类中的位置,在该字符类中它不能符合其正常含义,并且似乎有效:

$ echo "fdsl[]" | grep -o "[][a-z ]+"
fdsl[]

相关内容

  • 没有找到相关文章

最新更新