我有这个正则表达式:
(?<=prefix).*$
它返回字符串“ prefix”之后的任何字符,并且在任何在线正则表达式引擎(例如https://regex101.com)上都能正常工作。问题是当我在bash中使用该正则表达式时:
grep '(?<=prefix).*$' <<< prefixSTRING
它不匹配任何东西。为什么该正则表达式不适用于grep?
.*$
匹配任何字符串直到行尾(或字符串结尾),而不仅仅是任何一个字符。
我有这个正则表达式:
(?<=prefix).*$
它返回字符串“ prefix”之后的任何字符,并且在任何在线正则表达式引擎(例如https://regex101.com)上都能正常工作。问题是当我在bash中使用该正则表达式时:
grep '(?<=prefix).*$' <<< prefixSTRING
它不匹配任何东西。为什么该正则表达式不适用于grep?
.*$
匹配任何字符串直到行尾(或字符串结尾),而不仅仅是任何一个字符。
Answers:
您似乎已经定义了正确的正则表达式,但是没有在命令行中设置足够的标志grep
来理解它。因为默认情况下grep
支持BRE并带有-E
标志,所以它支持ERE。您所拥有的(先行)仅在PCRE regex风格中可用,仅在grep
带有其-P
标志的GNU中受支持。
假设您需要在添加一个额外的标志后仅提取匹配的字符串,以便知道仅将匹配的部分打印为prefix
-o
grep
grep -oP '(?<=prefix).*$' <<< prefixSTRING
grep
默认情况下,还有一个版本支持PCRE库- pcregrep
您可以在其中执行
pcregrep -o '(?<=prefix).*$' <<< prefixSTRING
美妙的Giles答案和实现每种正则表达式的工具均详细解释了各种正则表达式
正则表达式有许多不同的风格。您显示的是类似Perl的正则表达式(PCRE,“ Perl兼容的正则表达式”)。
grep
执行POSIX正则表达式。它们是基本正则表达式(BRE)和扩展正则表达式(ERE,如果grep
与该 -E
选项一起使用)。请参阅系统上的手册re_format
或regex
类似手册grep
,或我刚刚链接到的POSIX标准文本。
如果使用GNU grep
,并且grep
与grep
特定于GNU的-P
选项一起使用,则可以使用类似Perl的正则表达式。
还要注意,默认情况下grep
返回行,而不是行的子字符串。同样,对于GNU grep
(和其他一些grep
实现),您可以使用该-o
选项从每行中仅获取与给定表达式匹配的位。
请注意,-P
和和-o
都是POSIX规范的grep
非标准扩展。
如果您不使用GNU grep
,则可以改用sed
获取字符串prefix
和行尾之间的位:
sed -n 's/.*prefix\(.*\)/\1/p' file
这样做是仅打印sed
设法将给定替换应用于的行。替换将替换与表达式(即BRE)匹配的整行,并替换为出现在string之后的那一部分prefix
。
请注意,如果prefix
一行上有多个实例,则sed
变体将在最后一个实例之后返回字符串,而GNU grep
变体将在第一个实例之后返回字符串(其中包括的其他实例prefix
)。
该sed
解决方案可以移植到所有类Unix系统中。
正如其他答案所指出的,grep
不要在lookbehinds中使用正则表达式风格(默认情况下,GNU grep
或其他版本完全不使用)。
如果发现自己无法使用GNU grep
或pcregrep
,则可以使用perl
。
与之等效的命令行为perl
:
perl -ne 'print if /(?<=prefix).*$/' <<< prefixSTRING
您将所需的正则表达式放在斜线之间。当您使用Perl时,这将使用Perl的regex风格。
print "$&\n" if ...
如果他们只想输出prefix