2012-05-02 8 views
4

これは愚かな質問です。私は、より複雑な何かのためにこれを必要とするが、のは、それを簡単にしましょう:これは愚かな置換である音訳オペレータの変数の使用

$i = quotemeta 'A'; 
$line =~ tr/a-z/$i-Z/; 

、これは資本のものに小文字を回す必要がありますが、いままで私が試したことは動作しません。

[OK]をので、私はこれが混乱の多くをもたらした参照、実際のコードは次のようになります。

$line =~ tr/A-Z/F-ZA-E/;

それはCaesers Chiperのalgorhytmでなければなりません。固定された文字数で変更したい場合はうまく動作しますが、変数が必要なので、必要な数の文字を変更することができます。しかし私はevalを出荷したいと思う Thnx

P.S.また、なぜs ///は範囲で動作しませんか?

答えて

4

:また

$i = quotemeta 'A' 
eval("\$line =~ tr/a-z/$i-Z/;"); 
+1

すべての 'eval'の後で最良のテスト' $ @ '、いいえ? – tchrist

+0

はい、おそらく良い考えです。 – happydave

4

tr///では、変数ではなくリテラル文字しか使用できないことに注意してください。したがって、tr/a-z/$i-Z/が機能しない場合は、tr/a-z/A-Z/を使用する必要があります。 perldoc perlopでは、tr///の詳細を読むことができ、また、補間または欠如に関する説明を見つけることができます。

文字列を大文字に変換するには、他の方法もありますが、 uc関数、または正規表現のエスケープシーケンス\U(大文字)と\L(小文字)を使用できます。例えば:

my $str = 'a'; 
my $uppercase = uc $str; 

正規表現:

my $str = 'abcdef'; 
$str =~ s/([a-z]+)/\U$1/; # $str is now 'ABCDEF' 
[a-z]

は場合によって影響を受けるすべての文字を含むであろう\p{CWU}を書かなければならないことを指摘tchrist。

更新:

あなたは、動的エンコーディング機能のいくつかの種類を作成しようとしている場合、私は引数を取り、そして周りに手動で文字を移動サブルーチンを示唆しています。

sub foo { 
    my ($str, $num) = @_; # num is how many characters to shift the alphabet 
    my @in = 'A' .. 'Z'; 
    my @out = @in[$num .. $#in, 0 .. $num-1]; 
    my %out = map { $in[$_] => $out[$_] } 0 .. $#in; 
    $str =~ s#(.)# $out{$1} // $1 #eg; # if key does not exist, use org 
    return $str; 
} 

大文字と小文字は区別されますが、小文字のキーを追加することで解決できます。

+0

を、あなたは非常に多くの* *大文字、 'ucfirst'用のために' uc'を使用する必要がありますタイトルケース、小文字の場合は 'lc'、折り畳みケースの場合はv5.16の' fc'です。決して厄介なASCIIの方法ではありません。 – tchrist

+0

@ tchristそして、それはどういう意味ですか?エスケープシーケンス?なぜそれは壊れているのですか? – TLP

+0

あなたは私を嫌いにしますが、実際にあなたが知っている '$ str =〜s /(\ p {CWU} +)/ \ U $ 1/g'を意味します。 '[a-z]'を見ることは、本当にポストASCII時代のアンチパターンです。 – tchrist

0

trは変数では機能しません。代わりにs ///(代入)を使用してください。

+0

このような置換は 'a-z'の範囲のようにどのように見えるでしょうか?これは答えではありません。 – TLP

+0

はい、私は///で範囲を取得できません 範囲を持ち、trやs以外の関数がありますか? – Zippie

+0

範囲を使用できます。私の答えに示したように。私の指摘は、キノシスはどのようにして '\ U'を指定していないということでした。 – TLP

2

あなたの例は、残念ながら良いものではありません。 trオペレータは変数の補間を受け入れません(どちらの場合も半分で)。 trを実際に使用している場合は、evalに頼らないと運が悪いですが、これはお勧めできません。 trを使用していない場合は、実際のコードを表示して、何が起こっているのかを確認して、さらに提案してください。

UPDATE

これはどう?

my %map; 
@map{'A'..'Z'} = ('F'..'Z','A'..'E'); 
s/[A-Z]/$map{$&}/g; 

ない、それはまだ本当かどうかわからが、一度時間$&時にひどいパフォーマンスの低下に起因するすべてのコストで回避されることになっていました。あなたはそう簡単に十分に行うことができます:あなたは本当にTRが必要な場合は、evalを使用することができ

s/([A-Z])/$map{$1}/g; 
+3

停止。この目的のために 'eval'を使用することについては、何も言及されていません。 Sheesh。 – tchrist

+0

私は質問を編集してより明確になるように編集しました – Zippie

+0

@tchrist恐らくそれは過度のことです。私は物事をハックアップするためにevalに頼るよりも、適切な技術を学ぶ方が良いと主張するだろう。 – TLP

関連する問題