$name ="%8B%B3%82%A6%82%C4"; 
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

と書くと

「%8B%B3%82%A6%82%C4」が「教えて」

となることはわかったのですが、
逆に「教えて」を「%8B%B3%82%A6%82%C4」にする方法がわかりません。
Javaスクリプトだとescapeというのを使えばできるみたいなのですが、
perlを使ってできる方法があれば教えて下さい。
またそういう機能を持ったライブラリなんかがあるのでしたらそれも教えてもらえるとありがたいです。

このQ&Aに関連する最新のQ&A

A 回答 (2件)

$name=~s/([^a-zA-Z0-9_.-])/uc sprintf("%%%02x",ord($1))/eg;



ですね。ちなみにCGI.pmの中にescape, unescapeというその機能の
関数がありますが、これは内部的に使うように設計されています。
つまりCGI.pmを使うと、CGIをプログラムするときは自動的に入出力で
変換してくれるので気にしなくてよくなるようになるのです。

この回答への補足

御回答有り難うございます。ただうちのコンピューター(Macintosh,MacJparl)で

$name="%8B%B3%82%A6%82%C4";
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
print"$name\n";
$name=~s/([^a-zA-Z0-9_.-])/uc sprintf("%%%02x",ord($1))/eg;
print"$name\n";

とやってみたのですが、

教えて
%8B%82%82

というふうにprintされます。

%8B%B3%82%A6%82%C4

となってほしいのに

%8B%82%82

になってしまうのです。
なぜでしょう。

補足日時:2001/05/12 19:59
    • good
    • 0

ああ、Jperlをおつかいなのですね。


では I18N::Japaneseモジュールの機能を一時的にオフにする
必要がありますね。
no I18N::Japanese;
$name =~ s/([^a-zA-Z0-9_.-])/uc sprintf("%%%02x",ord($1))/eg;
use I18N::Japanese;

MacOSが手元にないので試せませんが、これでうまくいくのではないですか。

先のコードはアルファベットか数字以外の字を一文字ずつ(1バイトずつ)
処理しようとしますが、Jperlだと正規表現の動作が変わり、全角文字
ひとつにマッチするので、つまり2バイトずつ処理してしまいます。
(お試しになったコードが妙に短いのはそのせいです。6バイトなので
%??が6個のはずが、「教えて」の3文字で3個になっています)

no I18N::Japanese;はこの正規表現その他日本語用の処理を一時的に
オフにする機能です。(jcode.plなどをお使いになるとき、同様の
処理をする必要があるのでご存知かもしれませんが)

この回答への補足

ありがとうございました。
うまくいきました。
$name="%8B%B3%82%A6%82%C4";
$name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

print"$name\n";

no I18N::Japanese;
$name =~ s/([^a-zA-Z0-9_.-])/uc sprintf("%%%02x",ord($1))/eg;
use I18N::Japanese;

print"$name\n";

としたらちゃんと

教えて
%8B%B3%82%A6%82%C4

とprintされました。

問題は完全に解決しました。

補足日時:2001/05/12 22:57
    • good
    • 0
この回答へのお礼

ありがとうございます。
サーバー上のCGIはちゃんと機能し、問題は解決しました。

マックでうまく行かなかったのはJperlだったからなのですか。

>では I18N::Japaneseモジュールの機能を一時的にオフにする
>必要がありますね。

それも試してみたいと思います。

でもCGI、perl、は本当に初心者で、今までコンピューターではPHOTOSHOPしか使ったことがなく、HTMLも一ヶ月前に勉強し始めたばかりというぐらいなので、「I18N::Japaneseモジュールの機能を一時的にオフにする 」ということをどうやってやったらいいのかちょっとわかりませんが、頑張って勉強してみます。仕事で必要なので0から猛烈に勉強中です。

適切、迅速、丁寧な御回答ありがとうございました。

お礼日時:2001/05/12 22:55

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

Q$wfurikae = 1 if ( &ccom::getShukujitsu( &com::tD( $wwy,$wwm,$wwd )) ne '' );がよく

$wfurikae = 1 if ( &ccom::getShukujitsu( &com::tD( $wwy,$wwm,$wwd )) ne '' );

というスクリプトがあったのですが、

$wfurikae = 1 の後に;もいれずifがきています。

違和感があります。

どのような意味になるのでしょうか。

宜しくお願い致します。

Aベストアンサー

そのまんまだと思いますよ。
if 以下の条件が真の時 $wfurikae = 1となります。
Perlはいろいろな書き方ができますので、こういう書き方もありです。
英語の文法の並びにする書き方です。

Q正規表現 \b123bと^123$は同じ?

perlの正規表現の部分を勉強しているのですがわからないところがあります。
/\b123\b/と/^123$/は同じ意味ですか?
同じだとしたら、/^~$/という書き方があるのに/\b~\b/はどういう場面で効果的なのでしょうか?

Aベストアンサー

違う意味です。

"/\b123\b/" はワードで区切られた "123" にマッチします。
"/^123$/" は "123" のみの行にマッチします。
つまり、以下のようになります。

123    /\b123\b/,/^123$/ のいずれにもマッチ
ABC 123 abc  /\b123\b/ のみにマッチ

QPrel正規表現で'$1$'.$saltのあたりが理解できない。

小生Perlを勉強中です。
Perl Codeに以下のようなパスワード暗号処理のサブルーチンが
ありましたが、読めません。教えて下さい。

sub encrypt{
local($inpw)=$_[0];
local(@SALT,$salt,$encrypt);

@SALT=('a'..'z','A'..'Z','0'..'9','.','\');
srand;
$salt=$SALT[int(rand(@SALT)).$SALT[int(rand(@SALT))];
$encrypt=crypt($inpw,$salt)||crypt($inpw,'$1$'.$salt);
return $encrypt;
}

とあります。
特に、下から3行目の($inpw,'$1$'.$salt)が
理解できません。
解説していただければ幸いです。

Aベストアンサー

過去に同様の質問がありました。ctpsysさんの疑問にすべて答えられるかどうかわかりませんが、すくなくとも
>下から3行目の($inpw,'$1$'.$salt)が理解できません
というご質問に対しては参考になるかと思います。

参考URL:http://oshiete1.goo.ne.jp/kotaeru.php3?q=74593,http://oshiete1.goo.ne.jp/kotaeru.php3?q=74593,

Q@{$protocol_name}

usr strict;
をつかって、

$protocol_name = "pppoe";

@{$protocol_name}

のような使い方をしたいと思っていますが、

Can't use string ("pppoe") as an ARRAY ref while "strict refs" in use at ./ctest.pl line 152, <RCFG2> line 7

のようにエラー表示がでてしまいます。
どうしたら回避できるでしょうか。

Aベストアンサー

@pppoe という配列を生成する段階でハッシュ等扱いやすい変数に格納しておくのが定石だと思います。

・ハッシュにハードリファレンスで格納する方法
$protocol{pppoe} = \@pppoe; # 代入
@{$protocol{$protocol_name}} # 参照
# @pppoeとしましたがもちろん無名配列でかまいません。

・分岐させる方法
if($protocol_name eq "pppoe"){
... = @pppoe;
}elsif ...

・シンボリックリファレンスだけ許可させる方法
no strict 'refs';

・%main::から引く方法
@{$main::{$protocol_name}}

Q[perl] $xxx == 1 or $xxx == 5 or $xxx == 11 などと書くが面倒です

タイトルの通りです

if文などで長々と書くのが面倒なのですが何かいい方法はないのでしょうか?
以前はif($xxx =~ /^1$|^5$|^11$/)などと書いていたのですが、正規表現を使うと処理が遅いんですね

なるべく処理が軽くて簡潔な書き方がありましたら紹介してください

Aベストアンサー

配列なら
my @array = (1, 5, 11);
if (grep {$_ == $xxx } @array) { ... }
とかかな. ハッシュなら
my %valid = ( 1 => 1, 5 => 1, 11 => 1 );
if ($valid{$xxx}) { ... }
のような感じ (「ハッシュを使った重複チェック」のバリエーション).
あ,
if ($xxx == (1 or 5 or 11)) { ... }
のような形は, (そのままじゃないけど) Perl6 でサポートされる予定になっています. いつのことかは知りませんが.


このカテゴリの人気Q&Aランキング

おすすめ情報