0

書き出すときに、HTML::Table特定の行をスキップしたい。これは、Web ページから取得して正規表現としてコンパイルするいくつかのユーザー パラメータに従って行う必要があります。

パラメーターは、または郵便番号NOT_*などの値を持つ大文字です。cc08

my $nameRegex =    ($NOT_NAME)  ? qr/$NOT_NAME/  : '';
my $rackRegex =    ($NOT_RACK)  ? qr/$NOT_RACK/  : '';
my $unitRegex =    ($NOT_UNIT)  ? qr/$NOT_UNIT/  : '';
my $addressRegex = ($NOT_ADDR)  ? qr/$NOT_ADDR/  : ''; 
my $townRegex  =   ($NOT_TOWN)  ? qr/$NOT_TOWN/  : '';
my $pcodeRegex =   ($NOT_PCODE) ? qr/$NOT_PCODE/ : '';

while ループ (他の場所の SQL クエリの場合) でデータを取得し、「これらのいずれかに一致しない限り」、この結果行を追加すると思います。

while ((my $id, my $name, my $rack, my $unit, my $town, my $address, my $pcode, my $lat, my $lon) = $select_sites->fetchrow_array()) {
        my $checkbox = "<input type='checkbox' name='FILTER_SITE' value='$id' $checked{$id} />";

        unless ($name =~ $nameRegex
            || $rack =~ $rackRegex
            || $unit =~ $unitRegex
            || $address =~ $addressRegex
            || $town =~ $townRegex 
            || $pcode =~ $pcodeRegex) {

            $rows++;
            $sitesResultSection->addRow($checkbox, $name, $rack, $unit, $town, $address, $pcode, $lat, $lon);
        }

正規表現を吐き出すと、次のようになります$NOT_RACK = "cc08"

  = qr//;
 (?-xism:cc08) = qr/cc08/;
  = qr//;
  = qr//; 
   = qr//;
  = qr//;

ただし、行がまったく追加されないという問題がありますが、"cc08" ではクエリの結果を 1 つだけ省略し、他のすべての結果を表示する必要があります。

HTML でこれを行っている理由は、SQL クエリに既に他のフィルターがあり (結果セットを大幅に制限している)、ユーザー入力に従ってそれらのフィルターを動的にするのは悪夢になるからです。

回答は受け入れられましたが、さらに問題がありました。

REGEXPこれは、クエリの条件に使用したのと同じ方法で、NOT_s を初期化した方法です。したがって、ユーザーが「市のラック名」を入力すると、ラックが表示されますCity

my $NOT_NAME = &useOrs(&trim($cgi->param('NOT_NAME')));
my $NOT_RACK = &useOrs(&trim($cgi->param('NOT_RACK')));
my $NOT_UNIT = &useOrs(&trim($cgi->param('NOT_UNIT')));
my $NOT_ADDR = &useOrs(&trim($cgi->param('NOT_ADDR')));
my $NOT_TOWN = &useOrs(&trim($cgi->param('NOT_TOWN')));
my $NOT_PCODE= &useOrs(&trim($cgi->param('NOT_PCODE')));

my $QUICK_SEARCH_SITES = &trim($cgi->param('QUICK_SEARCH_SITES'));
my $searchRegexp = ($QUICK_SEARCH_SITES) ? &useOrs($QUICK_SEARCH_SITES) : '.*';

sub useOrs {
    my $tmp = $_[0];
    $tmp =~ s/\s+/|/g;
    return $tmp;
}

以下は SQL クエリからの抜粋WHERE name REGEXP ? OR rack-id REGEXP ? OR [..] です。これらのハックを使用すると、ツールを使用するサルを訓練する必要なく、適度な柔軟性が得られます。ただし、単に使用$var =~ /$NOT_VAR/すると、大文字と小文字が区別されるなど、正確にのみ一致するようです。SQLフィルターの緩さを実現するには、使用する代わりに使用し&useOrsます

sub useAny {
    my $tmp = $_[0];
    $tmp =~ s/\s/./g;
    return $tmp;
}

最も重要な$var =~ /.*$NOT_VAR.*/i

私はPerlでハックするべきだという印象を受けていたので.. :) 提案は大歓迎です。

4

2 に答える 2

4

perldoc perlopから:

空のパターン//

PATTERN が空の文字列に評価された場合、最後 に正常に一致した正規表現が代わりに使用されます。この場合、空のパターンの "g" フラグと "c" フラグのみが受け入れられます。他のフラグは元のパターンから取得されます。以前に一致が成功しなかった場合、これは (サイレントに) 代わりに本物の空のパターンとして機能します (これは常に一致します)。

したがって、以下を使用して生活を楽にすることができます。

my $nameRegex = qr/$NOT_NAME/;
my $rackRegex = qr/$NOT_RACK/;
my $unitRegex = qr/$NOT_UNIT/;
my $addressRegex = qr/$NOT_ADDR/; 
my $townRegex  = qr/$NOT_TOWN/;
my $pcodeRegex = qr/$NOT_PCODE/;

または、ハッシュを使用することをお勧めします (コードはテストされていません)。

use List::MoreUtils qw( any );

my %patterns = (
    name => qr/$NOT_NAME/,
    rack => qr/$NOT_RACK/,
    unit => qr/$NOT_UNIT/,
    address => qr/$NOT_ADDR/,
    town => qr/$NOT_TOWN/,
    pcode => qr/$NOT_PCODE/,
);

while (my $row = $select_sites->fetchrow_hashref("NAME_lc")) {
    my $checkbox = '...';

    next if any { $row->{$_} =~ $patterns{$_} } keys %patterns;

    $rows++;
    $sitesResultSection->addRow(
        $checkbox,
        @{ $row }{qw(name rack unit town address pcode lat lon)}
    }
}

これは、列名が使用した変数名と一致することを前提としています。

最後に、whereSQL で節を使用していますselectか? 可能であれば、データを取得する前にどの行を除外するかを指定する方がはるかに優れています。

たとえば、select name, rack, unit, address, town, pcode lat lon from TABLE where rack <> 'cc08' and town <> 'Concord'またはそれらの線に沿った何か。

于 2012-05-01T16:42:41.757 に答える
1

アップデート:

Sinan Ünür が指摘したように、perlopで説明されている隠された機能があり、空の正規表現//は代わりに最後に一致した正規表現を使用します。非常に奇妙な機能、IMO、この場合、微妙なエラーが発生します。

そのため、最初に内容がチェックされない限り、正規表現内で変数を使用することはお勧めできません。

解決:

あなたがすべきことは、IMO、これをサブルーチンに交換することです。

sub check_var {
    my ($var, $NOT_VAR) = @_;
    return 0 unless $NOT_VAR;
    return ($var =~ /$NOT_VAR/);
}

そして、それを次のように使用します。

unless ( check_var($name, $NOT_NAME) 
      || check_var($rack, $NOT_RACK)
      ....
于 2012-05-01T16:35:09.497 に答える