我试图将[
和]
与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规范:
- [...]右支架(
']'
)应失去其特殊含义,如果在列表中首先发生(在初始绕行后('^'
)(如果有)),则在括号表达式中表示自己。否则,它应终止括号表达式,除非它出现在整理符号(例如"[.].]"
)中,或者是整理符号,等效类或字符类的结尾右支架。特殊字符'.'
,'*'
,'['
和''
(分别为星号,左支架和后斜线)在括号表达式中应失去其特殊含义。
和
- [...]如果括号表达式指定
'-'
和']'
,则应首先放置']'
(如果有的话,'^'
之后)和'-'
在支架表达式内持续。
因此,您的正则应为:
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[]