1

这并不奇怪:

% perl -ne 'print if /c++/' foo
Nested quantifiers in regex; marked by <-- HERE in m/c++ <-- HERE / at -e line 1.

但这有点像:

% grep c++ foo
blah c++ blah

我不知道 grep 正在做什么来适应++-- 但我希望在 perl 中也一样。或者,至少,有一些优雅的方式来处理这种情况;该模式来自用户,他可能会看到该模式grep c++有效,然后对 perl 中的失败感到惊讶。

我不想使用quotemeta; 我的真实代码需要正则表达式模式(来自用户):

while ( my $pattern = shift @pat_list ) {
    my $regex = $opts{case} ? qr/$pattern/ : qr/$pattern/i;
    my @hits = grep { /$regex/ } @lines;

我想我可以检测到模式有错误然后恢复到quotemeta. 但我似乎无法eval用来捕获错误(因为它被视为语法错误?)。

4

4 回答 4

4

shell 命令grep至少知道三种解释正则表达式的模式:作为基本 RE(默认)、作为扩展 RE(如果使用-E或 as调用egrep)和 Perl 兼容 RE(如果使用 调用-P)。对于习惯于 Perl 的 RE 引擎的人来说,基本 RE 的行为有很大不同。grep的文档说明了您的特定用例:

In basic regular expressions the meta-characters ?, +, {, |, (, and ) lose
their special meaning; instead use the backslashed versions \?, \+, \{, \|, \(,
and \).

这意味着对 的调用中没有元字符grep c++ something.txt

请注意,即使 Perl 兼容的 RE(由知名库提供libpcre)也与 Perl 自己的 RE 引擎实现的并不完全相同。Perl 引擎的功能集在所有 RE 实现中非常独特。但是来自 libpcre 的 PCRE(与 Perl 兼容的 RE)至少非常相似并且也被广泛使用,例如在 PHP、C++(Boost)、类似grep和大多数其他编程语言的工具中。

话虽如此:我建议如果您想在 Perl 和 with 中使用大多数 RE,grep然后使用grep的 Perl 兼容模式,例如grep --perl-regexp $yourRE $yourFile.txt. 如果您允许任意用户输入,还要确保注意 shell 引用!有String::ShellQuote

于 2012-12-07T13:53:35.043 回答
1

如果您想要 grep 兼容 (POSIX) 正则表达式,您可以使用POSIX::Regex。(它不是标准模块,您可能需要使用 cpan 命令安装它。)

于 2012-12-07T13:37:11.317 回答
0

我的问题的主要观点是错误的。这工作正常:

#!/usr/bin/perl -w
use strict;
my $pattern = "c++";
my $regex;
eval { $regex = qr/$pattern/; };
warn "Error detected: $@" if $@;

我已要求删除我的问题。很抱歉浪费了大家的时间。

于 2012-12-07T16:10:14.550 回答
0

perl -ne '打印如果 /c\+\+/' foo

在正则表达式中,“+”表示“一个或多个”。

于 2012-12-07T18:31:56.073 回答