1

私のプログラムにはascii.txtが含まれており、そこからパターンを照合します。私のプログラムはsedコマンドを実装することで、perl を勉強しているので perl コードを書こうとしています。

#!/usr/bin/perl
# sed command implementation
use strict;
use warnings;
use subs qw(read_STDIN read_FILE usage);
use IO::File;
use constant {
    SEARCH_PRINT => 0,
};

our $proj_name = $0;

main(@ARGV);

sub main
{
    if(scalar @_ == 2) {
        read_FILE @_;

    }
    else {
        usage 
    }
}

sub read_FILE {
    my ($sed_script, $file_name) = @_;
    my $parsed_val =  parse_sed_script($sed_script);
    if( $parsed_val == SEARCH_PRINT ) {
        search_print_lines($sed_script, $file_name);
    }
}

sub parse_sed_script {
    my $command = shift or return;
    if($command =~ /^\/([^\/].)*\/$/) {
        return SEARCH_PRINT;
    }
}

sub search_print_lines {
    my ($script, $file) = @_;
    my $fh = IO::File->new($file, "r") or error("no file found $file");
    while( $_ = $fh->getline ) {
        print if $_ =~ $script
    }
}

sub usage {
    message("Usage: $proj_name sed-script [file]")
}

sub error
{
    my $e = shift || 'unkown error';
    print("$0: $e\n");
    exit 0;
}

シェルから実行すると:sed.pl /Test/ ascii.txt

print if $_ =~ $scriptが実行されないことがわかりました。これは、REGEX がスカラー変数に格納されているためです。

ascii.txtに含まれています。

Test 1
REGEX TEST

サブルーチンで使用するprint $scriptと、ユーザーから送信された正規表現が出力されますsearch_print_lines

4

2 に答える 2

3

コマンド ラインで何かを渡してスクリプトで使用すると、リテラル テキスト全体が使用されます。したがって、 を渡すと/Test/、これらのスラッシュがリテラルとして認識されるため、見ている「実際の」正規表現は次のよう\/Test\/になります (スラッシュをエスケープします。これは、スラッシュを探しているためです。// で囲まずに正規表現を渡してみてください) .

// が正規表現であることを示すことが目的の場合は、プログラムの開始時に // を削除します。

もう1つの編集:フラグを渡すことができるようにしたい場合は、何らかの方法で入力を評価する必要があります。

$script = '/Test/i';
eval { "\$regex = $script" };

その後

"REGEX TEST" =~ $regex

true を返す必要があります。ただし、このような評価を行うことは非常に安全ではありません。

編集: 何が起こるかとevalいうと、ブロック内にあるものは何でも実行されます。上記の eval では、動的に正規表現を作成し、それを変数に設定しています。これにより、コマンドライン入力の特別な解析を行うことなく、i のような正規表現フラグを使用できます。eval が実行されると、 を入力したかのようになります$regex = /Test/i。次に、テキストを比較する$regexと機能します。比較で大文字と小文字を区別しないように i フラグを設定しない限り、例が機能しないため、これについて考えました。

于 2013-08-02T22:49:04.263 に答える
1

$sed_script 変数からスラッシュを削除していません。read_FILE 関数を変更した後、機能し始めました。

sub read_FILE {
    my ($sed_script, $file_name) = @_;
    my $parsed_val =  parse_sed_script($sed_script);

    if( $parsed_val == SEARCH_PRINT ) {
        $sed_script =~ s/^\/(.*)\/$/$1/;

        #you can also parse the regexp
        #$sed_script = qr/$sed_script/;
        search_print_lines($sed_script, $file_name);
    }
}
于 2013-08-02T23:01:34.610 に答える