Perlのプログラムでコード変換の説明

このQ&Aのポイント
  • Perlのプログラムでコード変換の説明をします。
  • コード変換のプログラムの上記の部分は、日本語のエスケープシーケンスを設定するためのものです。
  • この部分では、日本語の文字コードの変換に使用されるエスケープシーケンスを定義しています。
回答を見る
  • ベストアンサー

Perlのプログラムで質問です

;# Set escape sequences which should be put before and after Japanese ;# (JIS X0208) string. ;# sub jis_inout { $esc_0208 = shift || $esc_0208; $esc_0208 = "\e\$$esc_0208" if length($esc_0208) == 1; $esc_asc = shift || $esc_asc; $esc_asc = "\e\($esc_asc" if length($esc_asc) == 1; ($esc_0208, $esc_asc); } ;# ;# Get JIS in and out sequences from the string. ;# sub get_inout { local($esc_0208, $esc_asc); $_[$[] =~ /($re_jis0208)/o && ($esc_0208 = $1); $_[$[] =~ /($re_asc)/o && ($esc_asc = $1); ($esc_0208, $esc_asc); } コード変換のプログラムの上記の部分を日本語で説明してください よろしくお願いします

  • Perl
  • 回答数2
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • mtaka2
  • ベストアンサー率73% (867/1179)
回答No.2

それで、jcode.pl の何が知りたいのでしょうか? 「jcode.plを使いたいから、その使い方が知りたい」のか 「perlの勉強のため、jcode.plを読み解いているが、コードの意味が分からない」のか、 その理由によって回答も変わってきます。 前者なら、ANo.1がほぼ答えの全てです。 詳しくは http://mikeneko.creator.club.ne.jp/~lab/kcode/jcode.html#h2-5 を読んでください。 後者だとしたら、まずは上記リンクを読んで、この関数の仕様を把握してください。内容は基本的に、仕様そのままです。 各行の処理内容は以下の通り。 ・jis_inout 1行目: jis_inout呼び出しの第一引数が指定されている場合は、それを$esc_0208 に代入します。指定されていない場合はもとのまま。 2行目: $esc_0208が1文字だけの場合は、頭に "\e\$"を補います。 3行目: jis_inout呼び出しの第一引数が指定されている場合は、それを$esc_asc に代入します。指定されていない場合はもとのまま。 4行目: $esc_ascが1文字だけの場合は、頭に "\e\("を補います。 5行目: 変更後のエスケープシーケンスを返します。 ・get_inout 1行目: ローカル変数の宣言 2行目: 引数文字列が $re_jis0208 にマッチするかどうか調べ、マッチする場合は、マッチした文字列を $esc_0208 に代入 3行目: 引数文字列が $re_asc にマッチするかどうか調べ、マッチする場合は、マッチした文字列を $esc_asc に代入 4行目: マッチした文字列のリストを返す となってます。

Zippyy
質問者

お礼

まさに後者の通りです。 わかりやすい説明に加え、参考サイトまで教えていただき本当にありがとうございました。

その他の回答 (1)

  • mtaka2
  • ベストアンサー率73% (867/1179)
回答No.1

挙げられたコードだけでは、各文の個々の意味はわかっても、全体でなにをやってるかははっきりとはわからないです。 特に、get_inout については、「$re_jis0208」「$re_asc」は何が入ってるのか不明ですし。 で、以下は多分に想像が含まれる推測というか、コメントを訳しただけの説明ですが、 jis_inout: 日本語(JIS X 0208)の前後に入れるエスケープシーケンスを返す get_inout: 引数で指定した文字列から、使われている日本語エスケープシーケンスを取得する じゃないでしょうか。 日本語文字列のバイト列としての表現方法(エンコーディング)には、Shift_JIS、EUC-JP、ISO-2022-JP、UTF-8などがありますが、ISO-2022-JP (いわゆるJIS)では、 ・ASCII文字列から日本語文字列への境目に、日本語文字列に切り替わることを示す文字列を入れる(通常は「\e\$B」、旧JISの場合は「\e\$@」) ・日本語文字列からASCII文字列への境目に、ASCII文字列に切り替わることを示す文字列を入れる(通常は「\e(B」、「\e\(J」の場合も) ようになってます。 http://x68000.q-e-d.net/~68user/webcgi/char-code-1.html#4 もっとも、昔の日本語に対応していなかたったころのperlで日本語処理する場合は、こういうコードを書く必要がありましたが、 今時のperlでは日本語文字列処理するライブラリが揃っていますので、こんなコードが必要になることはありません。 何のコードを読み解こうとしているのかわかりませんが、見ているコードが今読むには古くさすぎるような気がします。

Zippyy
質問者

補足

すみません、説明が不足していました 質問のプログラムはjcode.plの一部になります

関連するQ&A

  • 初歩的な質問なのですが

    以下の2つの関数から「内部変数」「引数」「戻り値」がどれかを知りたいのですが、 戻り値:「$esc_0208」「$esc_asc」 引数:なし であっているでしょうか? 変数は「$esc_0208」と「$esc_asc」のようにも思えるのですが、変数であり戻り値でもあるということでしょうか? sub jis_inout { $esc_0208 = shift || $esc_0208; $esc_0208 = "\e\$$esc_0208" if length($esc_0208) == 1; $esc_asc = shift || $esc_asc; $esc_asc = "\e\($esc_asc" if length($esc_asc) == 1; ($esc_0208, $esc_asc); } sub get_inout { local($esc_0208, $esc_asc); $_[$[] =~ /($re_jis0208)/o && ($esc_0208 = $1); $_[$[] =~ /($re_asc)/o && ($esc_asc = $1); ($esc_0208, $esc_asc); }

    • ベストアンサー
    • Perl
  • 日本語文字列の指定長(byte)切出し

    以下は日本語文字列(EUC)の指定長(byte)切出し関数なのですが、 これをShift-JIS版にするにはどうすれば良いのでしょうか? ================================================================ sub jcut { # 日本語文字列(EUC)の指定長(byte)切出し local($string, $length) = @_; if (substr($string,$length-1,1) =~ /[\x80-\xff]/) { $length++; } return substr($string, 0, $length); } ================================================================ 宜しくお願い致します。

  • GETデータの&で区切った個々のエラー処理について質問です。

    GETデータ、たとえば http://www.yahoo.co.jp/test.cgi?data1=1237&data2=AK とある場合、$ENV{'QUERY_STRING'}の中のそれぞれの引数値に個別にエラー処理をかける方法を教えてください。順番はdata2が先頭にくるときもあればdata1が先頭にくるときもあります。data以外の文字はだめです。たとえばcode1=となるとエラーになるようにしたい。data1には数字4文字が入ります。data2には大文字の英字が入ります。 組み合わせはdata1=8544だけのときもありますし、 data1=1234&data2=KOのときもあったりばらばらです。 逆の場合もあります。data2=KO&data1=1234というふうに・・・。$ENV{'QUERY_STRING'} を&で分割して@getにいれてから、@getから&で区切られた個々の値を取り出す方法がわかりません。。。 どなたかご教授ねがいます。よろしくお願いいたします。以下のように書いたのですがうまくできません。 sub err_check{ if ( $FORM{'action'} eq "" ) { local(@get); if($ENV{'QUERY_STRING'} !~ /data1|data2|data3/) { &err2; } if (length($ENV{'QUERY_STRING'}) > 30) { &err2; } (@get)=split(/&/,$ENV{'QUERY_STRING'}); foreach $getname (@get) { ##data1のとき if ($data1){ if ($getname !~ /^media=[0-9]+[0-9]+[0-9]+[0-9]/) { &err2; } if (length($data1) > 6) { &err2; } if (length($data1) < 4) { &err2; } } ##data2のとき if($data2){ if ($getname !~ /^data2=[A-Z]+[A-Z]/) { &err2; } if (length($data2) ne 2) { &err2; } }  } }

    • ベストアンサー
    • Perl
  • VBAでWebクエリにて情報を自動収集するプログラム

    自動売買ロボット作成マニュアルという本を買いました。 これは株などを自動売買するプログラムを作るための方法が書いた本です。(言語はエクセルに搭載されてあるVBAというプログラム言語です) そのプログラムを作る過程で、まずYahoo!ファイナンスから株価などの情報を10年分自動収集するプログラムを作ったのですが、「インターネットサーバーに接続できません」と出て、きちんと実行できません。 そこで、デバックをすると.Refresh BackgroundQuery:=Falseというプログラムのところがチェックされました。どうしたらいいでしょうか? この文章だけでは対処できないと思いますのでプログラムを書いておきます。長々とお読みいただきありがとうございます。どうかお知恵をお貸しください。 Dim url As String Dim lastrow As Integer Dim i As Integer Sub Get_Data() With ActiveSheet.QueryTables.Add(Connection:=url, Destination:=Cells(lastrow, 2)) .Name = _ "t?s=998407.o&a=4&b=22&c=2008&d=7&e=24&f=2008&g=d&q=t&y=0&z=998407.o&x=_1" .FieldNames = True .RowNumbers = False .FillAdjacentFormulas = False .PreserveFormatting = True .RefreshOnFileOpen = False .BackgroundQuery = True .RefreshStyle = xlInsertDeleteCells .SavePassword = False .SaveData = True .AdjustColumnWidth = True .RefreshPeriod = 0 .WebSelectionType = xlSpecifiedTables .WebFormatting = xlWebFormattingNone .WebTables = "19" .WebPreFormattedTextToColumns = True .WebConsecutiveDelimitersAsOne = True .WebSingleBlockTextImport = False .WebDisableDateRecognition = False .WebDisableRedirections = False .Refresh BackgroundQuery:=False End With End Sub Sub Calc() Dim code As String Dim data_length As Integer, date_temp As Date Dim day_s As Integer, month_s As Integer, year_s As Integer Dim day_e As Integer, month_e As Integer, year_e As Integer Dim row_length As Integer code = "998407.o" data_length = -3650 date_temp = DateAdd("d", data_length, Now) day_e = Day(Now) month_e = Month(Now) year_e = Year(Now) day_s = Day(date_temp) month_s = Month(date_temp) year_s = Year(date_temp) Range("B4:H65000").ClearContents For i = 0 To Abs(data_length) * 0.65 Step 50 url = "URL; http://table.yahoo.co.jp/t?s=" & code & "&a=" & month_s & "&b=" & day_s & "&c=" & year_s & "&d=" & month_e & "&e=" & day_e & "&f=" & year_e & "&g=d&q=t&y=" & i & "&z=" & code & "&x=.csv" If i = 0 Then lastrow = "4" Call Get_Data If Range("B4") = "" Then Exit Sub End If Else lastrow = (Range("B4").End(xlDown).Row + 1) Call Get_Data Range("B" & lastrow, "H" & lastrow).Delete row_length = (Range("B4").End(xlDown).Row) If row_length - lastrow < 49 Then Exit For End If End If Next Range("B5:H65000").Sort Key1:=Columns("B") lastrow = Range("B4").End(xlDown).Row Range("B5", "B" & lastrow).NumberFormatLocal = "yyyy/mm/dd" Range("C5", "H" & lastrow).NumberFormatLocal = "0" Range("A1").Select End Sub

  • 日本語(ひらがな・カタカナ・漢字)があるか判断する

    日本語(ひらがな・カタカナ・漢字)があるか判断する方法 Sub test1() Dim Str As String Dim MidStr As String Dim i As Long Str = "aiu123あいう" For i = 1 To Len(Str) MidStr = Mid(Str, i, 1) If Asc(MidStr) < 0 Then MsgBox "日本が混ざっています" Exit Sub End If Next End Sub このマクロを実行すると、「あ」の順番になった時にうまく反応するのですが、 いまいちASC関数についてよくわからないので教えてください。 ASC関数でマイナスになるものは全て日本語なのでしょうか? Asc(MidStr) < 0でいいのか、そこが知りたいです。 a→97 i→105 u→117 1→49 2→50 3→51 あ→-32096 い→-32094 う→-32092 でした。 ご回答よろしくお願いします。

  • VisualBasic.NETでのソースの意味がわかりません…。

    Dim misscount As Integer Dim istypemode As Boolean Private Sub button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Dim s() As String = New String() {"datemasamune", "sanadayukimura", "tyousokabemototika", "morning", "hyper", "newspaper"} Dim word As String = s(New Random().Next(0, s.GetUpperBound(0) + 1)) Label1.Text = word Label2.Text = "" istypemode = True End Sub Private Sub Form1_keypress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles MyBase.KeyPress If istypemode And Not Char.IsControl(e.KeyChar) Then If e.KeyChar = Label1.Text.Chars(Label2.Text.Length) Then Label2.Text &= e.KeyChar End If End If End Sub ------------- 以上のソースがあるのですが、どこでどうなっているというのを教えてほしいです。 もし意味不明な部分とかありましたら教えてください。

  • CGI間のデータ送信について(perl)

    perlのcgiで詰まってしまったので質問します。 現在困っていることは、cgiからcgiへの変数の値の受け渡しについてです。 色々調べてやってみたのですが、うまくいきません。 送信側で print "<form action = \"sendmail.cgi\" method=\"post\">"; print "<A href =\"sendmail.cgi?$array1[0]&$array1[1]&$array1[2]&$array1[3]\">sendmail.cgi</A>"; print "<input type=\"submit\" value=\" ボタンです。 \">"; print "</form>"; として 受信側で # postでもgetでも受信できるようにする if ($ENV{'REQUEST_METHOD'} eq "GET") { $data = '1'; $testmsg = "GETで受信"; $formdata = $ENV{'QUERY_STRING'}; print("$formdata<BR>"); } elsif ($ENV{'REQUEST_METHOD'} eq "POST"){ # こちらを使用している $data = '2'; $testmsg = "POSTで受信"; $length = $ENV{'CONTENT_LENGTH'}; read(STDIN,$formdata,$ENV{'CONTENT_LENGTH'});# $dataに受信する print("$formdata<BR>"); } else { $data = '3'; $testmsg = "受信することができませんでした。<BR>"; } としてpostにて受信しようとしています。 postのif文には入ったようなのですが、データが空っぽで何も入っていないようなのです。 何が原因なのでしょうか?助けてほしいです。

    • 締切済み
    • CGI
  • 文字列比較

    最長10文字の文字列を2件入力し、char型の配列にそれぞれ格納する。2つの文字列を比較し、文字列が同じだったら「equal」を表示し異なっていたら「Not equal」を表示するプログラムを作成せよという課題が出ました。 条件として、11文字以上の文字が入力されたら、先頭から10文字までを有効とし、11文字目以降を無視する。下記のプログラムで文字列1に11文字以上入力すると、うまく動きません。なぜ、うまくいかないかと、どうなおしたらよいかを教えてください。 #include<stdio.h> #include<string.h> #define max_length 10 void get_string (char *p_str, int size); int main() { char string1[max_length+2]; char string2[max_length+2]; printf("文字列1:"); get_string(string1,max_length+2); printf("文字列2:"); get_string(string2,max_length+2); if(!strncmp(string1,string2,max_length)) puts("equal"); else puts("Not equal"); } void get_string (char *p_str, int size) { fgets(p_str,size,stdin); }

  • 16進数

    Private Sub Text1_KeyPress(KeyAscii As Integer) If KeyAscii >= Asc("a") And KeyAscii <= Asc("f") Then Else KeyAscii = 0 Beep End If End Sub 上のソースだと数字が入りません。 どうすれば入力できますか。 ※zと入れると強制終了になってしまうので、上のソースを入れたんですが・・・ ※タグが崩れて見にくくてすいません

  • Javaのプログラムの質問です。

    Javaのプログラムについての質問です。 Listインターフェースの実装クラスの自作と、作成したクラスの全メソッドを呼び出すサンプルを作成せよ、という問題です。  注意点として、java.util.Listの実装クラスは使用出来ません(ArrayListなど)。実装するメソッドは、コードの中に番号を振ってあります。 import java.util.Collection; import java.util.Iterator; import java.util.ListIterator; import java.util.List; class LocalList implements List{  private int Count;  private String Data[];  private Iterator ite;  private ListIterator lite;  // コンストラクタ  void mylist(){   Data = new String[10];   Count = 0;  }  (1)  public boolean add(Object str){   if(Count >= 10){    return false;   }   Data[Count ++] = new String((String)str);   return true;  }  public void add(int i,Object str){  }        public boolean addAll(Collection c){   return false;  }        public boolean addAll(int i,Collection c){   return false;  }    (2)  public void clear(){   Count = 0;  }  public boolean contains(Object str){   return false;  }          public boolean containsAll(Collection c){   return false;  }  public boolean equals(Object str){   return false;  }    (3)  public Object get(int i){   return (i >= Count);  }  public int hashCode(){   return -1;  }  public int indexOf(Object str){   return -1;  }  public boolean isEmpty(){   return false;  }  public Iterator iterator(){   return ite;  }     public int lastIndexOf(Object str){   return -1;  }     public ListIterator listIterator(){   return lite;  }     public ListIterator listIterator(int i){   return lite;  }    (4)  public Object remove(int i){   return (i >= Count);  }    public boolean remove(Object str){   return true;  }         public boolean removeAll(Collection c){   return false;  }         public boolean retainAll(Collection c){   return false;  }    (5)  public Object set(int i,Object str){   return Data[i];  }    (6)  public int size(){   return Count;  }  public List subList(int i,int j){   return this;  }  public Object[] toArray(){   return Data;  }  public Object[] toArray(Object[] a){   return Data;  } } class Main {  public static void main(String[] args) {   mylist sub = new mylist();   sub.add("ビルドバーニングガンダム");   sub.add("ライトニングガンダム");   sub.add("ウイニングガンダム");   sub.add("ガンダムフェニーチェリナーシタ");   sub.add("R・ギャギャ");   for(int i = 0; i < sub.size(); i++){      System.out.println(sub.get(i));   }   // 改行   System.out.println();   // setメソッド   sub.set(1,"ガンダムエピオン");   for(int i = 0; i < sub.size(); i++){    System.out.println(sub.get(i));   }   // 改行   System.out.println();   // sizeメソッド   System.out.println("\r\n" + "機体数は" + sub.size() + "です" + "\r\n");   // removeメソッド   sub.remove(1);   for(int i = 0; i < sub.size(); i++){       System.out.println(sub.get(i));   }   // clearメソッド   sub.clear();   System.out.println("\r\n" + "機体数が" + sub.size() + "になったので負けです");    } } setメソッドとremoveメソッド以外は起動するのようになったのですが、この2つがうんともすんとも動きません。ジェネリクス型を使うという考え方もあるらしいのですが、ネットで調べてもピンと来ず寸詰まり状態になってしまっています。後少しだと思うのですが。。。。 どなたかご教授頂けないでしょうか?よろしくお願い致します。

専門家に質問してみよう