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

シェルコマンドgrepは、正規表現を解釈する方法について、少なくとも3つのモードを認識しています。基本RE(デフォルト)、拡張RE(-Eまたはとして呼び出される場合egrep)、およびPerl互換RE(で呼び出される場合-P)です。基本的なREは、Perlの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とでほとんどのREを使用したい場合は、Perl互換モードをgrep使用することをお勧めします。また、任意のユーザー入力を許可する場合は、シェルの引用に注意してください。そのためのString::ShellQuoteがあります。grepgrep --perl-regexp $yourRE $yourFile.txt

于 2012-12-07T13:53:35.043 に答える
1

grep 互換 (POSIX) 正規表現が必要な場合は、POSIX::Regexを使用できます。(標準モジュールではありません。cpan コマンドでインストールする必要がある場合があります。)

于 2012-12-07T13:37:11.317 に答える
0

perl -ne 'print if /c\+\+/' foo

正規表現では、「+」は「1 つ以上」を意味します。

于 2012-12-07T18:31:56.073 に答える
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 に答える