如何在Perl中引用长字符串?

时间:2010-09-14 08:37:33

标签: perl string quotes

我通常使用简单的引号,但有时我得到很长的行,我无法破解,也需要使用转义字符,所以我得到这样的东西:

my $str = "select query_accession,query_tag,hit_accession,hit_tag,significance from summaryTables where query_id = \'$query_id\';"

我知道在Perl中表示字符串还有其他各种方法。你会推荐什么?

更新 感谢所有人提供与SQL相关的建议。我学到了一些有价值的东西,但是,我的问题仍然存在(作为一般问题,无论SQL如何):是否有一些操作符允许引用而不会捕获换行符?

我现在做的是:

my $str = "123 123 456 sdndfnd sdfdmd " .
 "dfsdjkfs 343489 dfjsdj 3 34kdfsk kd " .
 "fd kd9534 rfg 546 5";

非常难看。

8 个答案:

答案 0 :(得分:10)

我喜欢这里的文件,虽然有些人鄙视他们,因为终结者必须出现在行的开头,尽管你的缩进级别。

my $str = <<"SQL";
  SELECT 
    query_accession,
    query_tag,
    hit_accession,
    hit_tag,
    significance
  FROM   
    summaryTables
  WHERE 
    query_id = ?
SQL

我也喜欢格式化我的SQL,所以我可以很容易地看到语句中的结构。

答案 1 :(得分:5)

查看perlop's Quote-Like Operators。使用qq表示双引号,q表示单引号。

答案 2 :(得分:3)

正如您引用的SQL那样,请考虑使用类似SQL::Abstract的内容来构建查询。

例如:

use SQL::Abstract;

my $sql = SQL::Abstract->new;
my $query_id = 'xyzzy';  # arbitary value

my ($query, @bind) = $sql->select( 
    'summaryTables',
    [qw/ query_accession query_tag hit_accession hit_tag significance /],
    { query_id => $query_id },
);

这是您在$query中看到的内容:

SELECT query_accession, query_tag, hit_accession, hit_tag, significance FROM summaryTables WHERE ( query_id = ? )

@bind

xyzzy

因此$query已构建为接受SQL占位符,@bind具有必要的值。所以它只是通常的DBI这样的东西来运行查询:

my $sth = $dbh->prepare( $query );
$sth->execute( @bind );

现在,您拥有SQL占位符提供的所有安全性和优化(请参阅SQL injection Wikipedia entry

另见以前的SO问题:Is there SQL parameter binding for arrays?

/ I3az /

答案 3 :(得分:3)

没有。所有Perl 5的字符串创建方法都知道并包含换行符。您可以像在问题中一样使用连接运算符,也可以抽象出解决问题所需的代码:

#!/usr/bin/perl

use strict;
use warnings;

sub single_line {
    my @strings = @_;
    for (@strings) {
        s/\s+/ /g;
        s/^\s+|\s+$//g;
    }
    return wantarray ? @strings : $strings[0];
}


my $sql = single_line "
    select query_accession,query_tag,hit_accession,hit_tag,significance
    from summaryTables
    where query_id = ?;
";

print "[$sql]\n";

答案 4 :(得分:2)

在您给出的示例中,没有理由不破坏该行,也不需要转义单引号。

my $str = "select query_accession,
                  query_tag,
                  hit_accession,
                  hit_tag,significance
           from   summaryTables
           where query_id = '$query_id';"

但是,正如其他人所指出的那样,对于将要传递给DBI的SQL查询中的替换,你最好使用占位符。

答案 5 :(得分:2)

对于一般文本构建( re:您的更新),一个奇特的答案是使用模板引擎。它有点像类固醇的printf

以下是使用Template Toolkit的示例:

sub buildtt {
    use Template;
    my $tt = Template->new( START_TAG => '{', END_TAG => '}' );
    $tt->process( \$_[0], $_[1], \my $output );
    return $output;
}

my $str = buildtt '{a} {b} {c}' => {
    a => "123 123 456 sdndfnd sdfdmd",
    b => "dfsdjkfs 343489 dfjsdj 3 34kdfsk kd",
    c => "fd kd9534 rfg 546 5",
};

您也可以像这样构建它:

my $str2 = buildtt '{all.join(" ")}' => {
    all => [ "123 123 456 sdndfnd sdfdmd",
             "dfsdjkfs 343489 dfjsdj 3 34kdfsk kd",
             "fd kd9534 rfg 546 5" ],
};

以下是一些引用等的例子:

my $str3 = buildtt '{all.join(" ")}' => {
    all => [ "no quoted text here",
             "here's some and here's some more",
             q{$str2 was "buildtt"},
             $str2 ],
};

更好的例子就是这样的原始SQL文本:

my $sql = buildtt 'select {v.join(",")} from {t} where {q}' => { 
    v => [qw/ query_accession query_tag hit_accession hit_tag significance /],
    t   => 'summaryTables',
    q   => '( query_id = ? )',
};

另见:


最后,从异国情调到奇怪,你甚至可以用quote-like operator创建一个新的PerlX::QuoteOperator

use PerlX::QuoteOperator q_strip_newline => {
    -emulate => 'q',
    -with    => sub ($) {
        my $txt = shift;
        $txt =~ s/\n//g;
        $txt;
    },
};

my $str = q_strip_newline{123 123 456 sdndfnd sdfdmd
dfsdjkfs 343489 dfjsdj 3 34kdfsk kd
fd kd9534 rfg 546 5};

/ I3az /

答案 6 :(得分:1)

在这种特殊情况下,我建议使用占位符,除非你绝对100%确定$ query_id永远不能包含“有趣的字符”

Obligatory xkcd reference

答案 7 :(得分:0)

虽然没有内置运算符来执行此操作,但这是另一种可行的方法:

(my $str = qq(
123 123 456 sdndfnd sdfdmd 
dfsdjkfs 343489 dfjsdj 3 34kdfsk kd 
fd kd9534 rfg 546 5
)) =~ s/\n//g;

或以两步形式:

my $str = qq(
123 123 456 sdndfnd sdfdmd 
dfsdjkfs 343489 dfjsdj 3 34kdfsk kd 
fd kd9534 rfg 546 5
);
$str =~ s/\n//g;

两者都很难看,但功能齐全。