=encoding euc-jp =head1 NAME =begin original perlfaq4 - Data Manipulation ($Revision: 10394 $) =end original perlfaq4 - データ操作 ($Revision: 10394 $) =head1 DESCRIPTION =begin original This section of the FAQ answers questions related to manipulating numbers, dates, strings, arrays, hashes, and miscellaneous data issues. =end original FAQのこのセクションでは、数値、日付、文字列、配列、ハッシュその他の データの取り扱いに関する質問に回答しています。 =head1 Data: Numbers (データ: 数) =head2 Why am I getting long decimals (eg, 19.9499999999999) instead of the numbers I should be getting (eg, 19.95)? (なぜ 19.95 のような数字ではなく、19.9499999999999 のような長い数字が出てきたんでしょうか?) =begin original Internally, your computer represents floating-point numbers in binary. Digital (as in powers of two) computers cannot store all numbers exactly. Some real numbers lose precision in the process. This is a problem with how computers store numbers and affects all computer languages, not just Perl. =end original 内部的には、あなたの使っているコンピュータは浮動小数点数を 2 進数を 使って表現しています。 (2 のべき乗のような) デジタルなコンピュータは全ての数値を正確に 保管することはできません。 実数は処理中に精度が落ちることがあります。 これはコンピュータがどのように数値を保管するかの問題で、Perl だけではなく 全てのコンピュータ言語に影響を与えます。 =begin original L shows the gory details of number representations and conversions. =end original L には、数値表現と変換に関する不愉快な詳細が記されています。 =begin original To limit the number of decimal places in your numbers, you can use the printf or sprintf function. See the L<"Floating Point Arithmetic"|perlop> for more details. =end original 10 進数の桁数を制限するには、printf や sprintf の関数が使えます。 更なる詳細については L<"Floating Point Arithmetic"|perlop> を参照してください。 printf "%.2f", 10/3; my $number = sprintf "%.2f", 10/3; =head2 Why is int() broken? (なぜ int() は壊れているのでしょう?) =begin original Your C is most probably working just fine. It's the numbers that aren't quite what you think. =end original C はほぼ確実に正しく動作しています。 これは、数値というものがあなたの考えているものと違うからです。 =begin original First, see the answer to "Why am I getting long decimals (eg, 19.9499999999999) instead of the numbers I should be getting (eg, 19.95)?". =end original まず、"Why am I getting long decimals (eg, 19.9499999999999) instead of the numbers I should be getting (eg, 19.95)?" に対する答えを参照してください。 =begin original For example, this =end original 例えば、これは: print int(0.6/0.2-2), "\n"; =begin original will in most computers print 0, not 1, because even such simple numbers as 0.6 and 0.2 cannot be presented exactly by floating-point numbers. What you think in the above as 'three' is really more like 2.9999999999999995559. =end original ほとんどのコンピュータでは 1 ではなく 0 を表示します; 0.6 や 0.2 と言った単純な数値であっても、浮動小数点数で正確に表現できません。 さきほどあなたが "3" と考えたものは、実際には 2.9999999999999995559 と いったものです。 =head2 Why isn't my octal data interpreted correctly? (なぜ私の 8 進データは正しく解釈されないのでしょうか?) =begin original Perl only understands octal and hex numbers as such when they occur as literals in your program. Octal literals in perl must start with a leading C<0> and hexadecimal literals must start with a leading C<0x>. If they are read in from somewhere and assigned, no automatic conversion takes place. You must explicitly use C or C if you want the values converted to decimal. C interprets hexadecimal (C<0x350>), octal (C<0350> or even without the leading C<0>, like C<377>) and binary (C<0b1010>) numbers, while C only converts hexadecimal ones, with or without a leading C<0x>, such as C<0x255>, C<3A>, C, or C. The inverse mapping from decimal to octal can be done with either the <%o> or C<%O> C formats. =end original Perl は、プログラムの中にリテラルとして現れたときにだけ 8 進数や 16 進数を 理解します。 perl での 8 進数リテラルは先頭に C<0> が必要で、16 進数リテラルは 先頭に C<0x> が必要です。 それらのものがそれ以外の場所からとか代入で読み込まれた場合、 変換は実行されません。 10 進数へ変換したいなら、陽に C や C を使わなければなりません。 C は 16 進数(C<0x350>)、8 進数(C<0350> や、C<377> のように 先頭の C<0> がないものでも)、2 進数(C<0b1010>) を解釈するのに対して、 hex() が 16 進数(C<0x255>, C<3A>, C, C のように、 先頭に C<0x> がついたりつかなかったりします)のみを変換します。 10 進数から 8 進数への逆変換は C の <%o> か C<%O> の フォーマットで行えます。 =begin original This problem shows up most often when people try using C, C, C, or C, which by widespread tradition typically take permissions in octal. =end original この問題は、パーミッションを 8 進数で指定するような広く広まった 伝統のために C, C, C, C を使おうと したときによく発生します。 chmod(644, $file); # WRONG chmod(0644, $file); # right =begin original Note the mistake in the first line was specifying the decimal literal C<644>, rather than the intended octal literal C<0644>. The problem can be seen with: =end original 1 行目の間違いは、意図している 8 進数リテラル C<0644> ではなく、 10 進数 リテラル C<644> を指定していることであることに注意してください。 問題点は、以下のようにすることで見られます: printf("%#o",644); # prints 01204 =begin original Surely you had not intended C - did you? If you want to use numeric literals as arguments to chmod() et al. then please try to express them as octal constants, that is with a leading zero and with the following digits restricted to the set C<0..7>. =end original きっと C は意図してないはずです - ですよね? chmod() などでの引数として数値リテラルを使いたい場合は、 先頭に 0 をつけ、その後に C<0..7> の数値が続く 8 進定数を使うように してください。 =head2 Does Perl have a round() function? What about ceil() and floor()? Trig functions? (Perl には丸め関数がありますか? ceil() と floor() とは何ですか? 三角関数は?) =begin original Remember that C merely truncates toward 0. For rounding to a certain number of digits, C or C is usually the easiest route. =end original C は 0 へ向かって丸めを行うことを思い出してください。 特定の桁数で丸めを行うには、C や C を使うことが 通常はもっとも簡単なやり方です。 printf("%.3f", 3.1415926535); # prints 3.142 =begin original The C module (part of the standard Perl distribution) implements C, C, and a number of other mathematical and trigonometric functions. =end original (標準 Perl 配布キットの一部である)C モジュールは C、 C、そしてその他の数学的な関数や三角関数の多くを実装しています。 use POSIX; $ceil = ceil(3.5); # 4 $floor = floor(3.5); # 3 =begin original In 5.000 to 5.003 perls, trigonometry was done in the C module. With 5.004, the C module (part of the standard Perl distribution) implements the trigonometric functions. Internally it uses the C module and some functions can break out from the real axis into the complex plane, for example the inverse sine of 2. =end original perl の 5.000 から 5.003 では、三角関数は C モジュールの中で 実行されていました。 5.004 では、C モジュール(標準 Perl 配布キットの一部です)が 三角関数を実装しています。 内部的にはこれは C を使っていて、一部の関数は実数値を複素数領域へ 変化させることができます。 2 の inverse sine がその一例です。 =begin original Rounding in financial applications can have serious implications, and the rounding method used should be specified precisely. In these cases, it probably pays not to trust whichever system rounding is being used by Perl, but to instead implement the rounding function you need yourself. =end original 金融に関係するアプリケーションにおいては、丸めはきちんとした実装を 必要とするかもしれません。 そして、丸めの方法は適切に使われるべきものです。 この場合、Perl が使っているシステムによる丸めを信用すべきではなく、 自分自身で丸め関数を実装するようにすべきでしょう。 =begin original To see why, notice how you'll still have an issue on half-way-point alternation: =end original なぜかを見るために、中間点反復に関する問題があるということに注意しましょう: for ($i = 0; $i < 1.01; $i += 0.05) { printf "%.1f ",$i} 0.0 0.1 0.1 0.2 0.2 0.2 0.3 0.3 0.4 0.4 0.5 0.5 0.6 0.7 0.7 0.8 0.8 0.9 0.9 1.0 1.0 =begin original Don't blame Perl. It's the same as in C. IEEE says we have to do this. Perl numbers whose absolute values are integers under 2**31 (on 32 bit machines) will work pretty much like mathematical integers. Other numbers are not guaranteed. =end original Perl を責めないでください。 これはCでも同じことなのです。 IEEE ではこのようにすることを述べています。 Perl での数値は絶対値で 2**31(32 ビットマシンの場合)以下の場合の整数値であれば 数学的な整数と同じように振る舞います。 それ以外の数値は恩恵を受けません。 =head2 How do I convert between numeric representations/bases/radixes? (数値表現や基底や基数を変換するには?) =begin original As always with Perl there is more than one way to do it. Below are a few examples of approaches to making common conversions between number representations. This is intended to be representational rather than exhaustive. =end original Perl ではいつものことですが、これを行うには複数の方法があります。 以下は、一般的な数値表現の変換を行うための手法のいくつかの例です。 これは完全性よりも説明性を意図しています。 =begin original Some of the examples later in L use the C module from CPAN. The reason you might choose C over the perl built in functions is that it works with numbers of ANY size, that it is optimized for speed on some operations, and for at least some programmers the notation might be familiar. =end original L の後の方での例では CPAN にある C を使っています。 perl 組み込みの関数よりも C を選択する理由は、 どんな大きさの数でも動作し、いくつかの操作では速度のために最適化されていて、 少なくともいくらかのプログラマにとっては表記がわかりやすいからです。 =over 4 =item How do I convert hexadecimal into decimal (16 進数を 10 進数に変換するには?) =begin original Using perl's built in conversion of C<0x> notation: =end original C<0x> 表記による perl の組み込み変換を使って: $dec = 0xDEADBEEF; =begin original Using the C function: =end original C 関数を使って: $dec = hex("DEADBEEF"); =begin original Using C: =end original C を使って: $dec = unpack("N", pack("H8", substr("0" x 8 . "DEADBEEF", -8))); =begin original Using the CPAN module C: =end original CPAN の C モジュールを使って: use Bit::Vector; $vec = Bit::Vector->new_Hex(32, "DEADBEEF"); $dec = $vec->to_Dec(); =item How do I convert from decimal to hexadecimal (10 進数を 16 進数に変換するには?) =begin original Using C: =end original C を使って: $hex = sprintf("%X", 3735928559); # upper case A-F $hex = sprintf("%x", 3735928559); # lower case a-f =begin original Using C: =end original C を使って: $hex = unpack("H*", pack("N", 3735928559)); =begin original Using C: =end original C を使って: use Bit::Vector; $vec = Bit::Vector->new_Dec(32, -559038737); $hex = $vec->to_Hex(); =begin original And C supports odd bit counts: =end original そして C は半端なビット数にも対応しています: use Bit::Vector; $vec = Bit::Vector->new_Dec(33, 3735928559); $vec->Resize(32); # suppress leading 0 if unwanted $hex = $vec->to_Hex(); =item How do I convert from octal to decimal (8 進数を 10 進数に変換するには?) =begin original Using Perl's built in conversion of numbers with leading zeros: =end original 先頭に 0 を付けることによる Perl 組み込みの変換を使って: $dec = 033653337357; # note the leading 0! =begin original Using the C function: =end original C function 関数を使って: $dec = oct("33653337357"); =begin original Using C: =end original C を使って: use Bit::Vector; $vec = Bit::Vector->new(32); $vec->Chunk_List_Store(3, split(//, reverse "33653337357")); $dec = $vec->to_Dec(); =item How do I convert from decimal to octal (10 進数を 8 進数に変換するには?) =begin original Using C: =end original C を使って: $oct = sprintf("%o", 3735928559); =begin original Using C: =end original C を使って: use Bit::Vector; $vec = Bit::Vector->new_Dec(32, -559038737); $oct = reverse join('', $vec->Chunk_List_Read(3)); =item How do I convert from binary to decimal (2 進数から 10 進数に変換するには?) =begin original Perl 5.6 lets you write binary numbers directly with the C<0b> notation: =end original Perl 5.6 から、C<0b> 表記を使って直接 2 進数を書くことができます: $number = 0b10110110; =begin original Using C: =end original C を使って: my $input = "10110110"; $decimal = oct( "0b$input" ); =begin original Using C and C: =end original C と C を使って: $decimal = ord(pack('B8', '10110110')); =begin original Using C and C for larger strings: =end original より大きな文字列に対しては、C と C を使って: $int = unpack("N", pack("B32", substr("0" x 32 . "11110101011011011111011101111", -32))); $dec = sprintf("%d", $int); # substr() is used to left pad a 32 character string with zeros. =begin original Using C: =end original C を使って: $vec = Bit::Vector->new_Bin(32, "11011110101011011011111011101111"); $dec = $vec->to_Dec(); =item How do I convert from decimal to binary =begin original Using C (perl 5.6+): =end original C を使って(perl 5.6 以降): $bin = sprintf("%b", 3735928559); =begin original Using C: =end original C を使って: $bin = unpack("B*", pack("N", 3735928559)); =begin original Using C: =end original C を使って: use Bit::Vector; $vec = Bit::Vector->new_Dec(32, -559038737); $bin = $vec->to_Bin(); =begin original The remaining transformations (e.g. hex -> oct, bin -> hex, etc.) are left as an exercise to the inclined reader. =end original 残りの変換 (16 進 -> 8 進、2 進 -> 16 進、など) は読者への宿題として 残しておきます。 =back =head2 Why doesn't & work the way I want it to? (なぜ & は私の思った通りに動作しないのでしょうか?) =begin original The behavior of binary arithmetic operators depends on whether they're used on numbers or strings. The operators treat a string as a series of bits and work with that (the string C<"3"> is the bit pattern C<00110011>). The operators work with the binary form of a number (the number C<3> is treated as the bit pattern C<00000011>). =end original バイナリ算術演算子の振る舞いはそれが数値に対して使われているのか 文字列に対して使われているかということに依存しています。 その演算子は文字列をビットの並びとして扱います(C<"3"> という文字列は C<00110011> というビットパターンとなります)。 この演算子はバイナリ形式に対して働きます (C<3> という数値は C<00000011> というビットパターンとして扱われます)。 =begin original So, saying C<11 & 3> performs the "and" operation on numbers (yielding C<3>). Saying C<"11" & "3"> performs the "and" operation on strings (yielding C<"1">). =end original ですから、C<11 & 3> は数値に対する "and" として働きます(結果は C<3> です)。 C<"11" & "3">は文字列に対する "and" として働きます(結果は C<"1"> です)。 =begin original Most problems with C<&> and C<|> arise because the programmer thinks they have a number but really it's a string. The rest arise because the programmer says: =end original ありがちな問題は C<&> と C<|> を使ったときに、プログラマは オペランドが数値と考えているのに実際は文字列であるようなときに 起こります。 例を挙げましょう: if ("\020\020" & "\101\101") { # ... } =begin original but a string consisting of two null bytes (the result of C<"\020\020" & "\101\101">) is not a false value in Perl. You need: =end original この場合の結果は二つのナルバイトを含む文字列となります (C<"\020\020"> の結果です)が、これは Perl における偽の値では ありません。 以下のようにする必要があります: if ( ("\020\020" & "\101\101") !~ /[^\000]/) { # ... } =head2 How do I multiply matrices? (行列の積を計算するには?) =begin original Use the Math::Matrix or Math::MatrixReal modules (available from CPAN) or the PDL extension (also available from CPAN). =end original Math::Matrix モジュールか、Math::MatrixReal モジュール(CPAN で入手できます)か PDL エクステンション(これも CPAN で入手できます)を使います。 =head2 How do I perform an operation on a series of integers? (整数値の並びに対してある操作を実行するには?) =begin original To call a function on each element in an array, and collect the results, use: =end original 配列の各要素に対して関数を呼び出して、結果を集めるにはこうします: @results = map { my_func($_) } @array; =begin original For example: =end original 例えば: @triple = map { 3 * $_ } @single; =begin original To call a function on each element of an array, but ignore the results: =end original 配列の各要素に対して関数を呼び出すけれども、結果を無視するという 場合にはこうします: foreach $iterator (@array) { some_func($iterator); } =begin original To call a function on each integer in a (small) range, you B use: =end original ある(小さな)範囲にある整数に対して関数を呼び出すには、こうも B<できます>: @results = map { some_func($_) } (5 .. 25); =begin original but you should be aware that the C<..> operator creates an array of all integers in the range. This can take a lot of memory for large ranges. Instead use: =end original ただし、C<..> 演算子がその範囲にあるすべての整数の配列を生成するということに 注意すべきでしょう。 これによって大きな範囲を使った場合に大量のメモリを消費することになります。 代わりにこうします: @results = (); for ($i=5; $i < 500_005; $i++) { push(@results, some_func($i)); } =begin original This situation has been fixed in Perl5.005. Use of C<..> in a C loop will iterate over the range, without creating the entire range. =end original この状況は Perl5.005 で修正されました。 C ループで C<..> を使うことで、 範囲全体を生成することなく特定の範囲の繰り返しを行えます。 for my $i (5 .. 500_005) { push(@results, some_func($i)); } =begin original will not create a list of 500,000 integers. =end original このようにしても 500,000 個の整数のリストが生成されたりはしません。 =head2 How can I output Roman numerals? (ローマ数字を出力するには?) =begin original Get the http://www.cpan.org/modules/by-module/Roman module. =end original http://www.cpan.org/modules/by-module/Roman モジュールを入手しましょう。 =head2 Why aren't my random numbers random? (なぜ私の乱数はランダムでないの?) =begin original If you're using a version of Perl before 5.004, you must call C once at the start of your program to seed the random number generator. =end original 5.004 より前のバージョンの Perl を使っているなら、C を プログラムの開始時点で一度呼び出してやって、乱数生成器の種を セットしてやらなければなりません。 BEGIN { srand() if $] < 5.004 } =begin original 5.004 and later automatically call C at the beginning. Don't call C more than once--you make your numbers less random, rather than more. =end original 5.004 以降のものでは開始時点で自動的に C を呼び出します。 二度以上 C を呼び出してはいけません。 乱数の質を落としてしまいます。 =begin original Computers are good at being predictable and bad at being random (despite appearances caused by bugs in your programs :-). see the F article in the "Far More Than You Ever Wanted To Know" collection in http://www.cpan.org/misc/olddoc/FMTEYEWTK.tgz , courtesy of Tom Phoenix, talks more about this. John von Neumann said, "Anyone who attempts to generate random numbers by deterministic means is, of course, living in a state of sin." =end original コンピュータは予測できる物事に関しては役に立ちますが、ランダムな ことに対してはそうではありません(それはあなたのプログラム自身のバグによって 引き起こされることですが:-) Tom Phoenix がこの問題について語っている、 http://www.cpan.org/misc/olddoc/FMTEYEWTK.tgz の "Far More Than You Ever Wanted To Know" の中の F という記事を 参照してください。 ジョン・フォン・ノイマン曰く、「決定論的手段によって 乱数を作ろうと試みる全ての人はもちろん罪深きものである。」 =begin original If you want numbers that are more random than C with C provides, you should also check out the C module from CPAN. It uses the imperfections in your system's timer to generate random numbers, but this takes quite a while. If you want a better pseudorandom generator than comes with your operating system, look at "Numerical Recipes in C" at http://www.nr.com/ . =end original C と C が提供するものよりもよりランダムな数値が必要なら、 CPAN にある C モジュールも チェックしてみると良いでしょう。 これはあなたの使っているシステムのタイマーを乱数を生成するのに 使っていて不完全な面もありますが、十分なものです。 あなたの使うオペレーティングシステムで使えるものよりも もっと良質な擬似乱数を必要としているのなら、 http://www.nr.com にある ``Numerical Recipes in C'' を見るとよいでしょう。 =head2 How do I get a random number between X and Y? (X と Y の間の乱数を得るには?) =begin original To get a random number between two values, you can use the C builtin to get a random number between 0 and 1. From there, you shift that into the range that you want. =end original 二つの値の間の乱数を得るためには、まず 0 と 1 との間の乱数を得るために C 組み込み関数を使います。 それから、これを必要な範囲にシフトします。 =begin original C returns a number such that C<< 0 <= rand($x) < $x >>. Thus what you want to have perl figure out is a random number in the range from 0 to the difference between your I and I. =end original C は C<< 0 <= rand($x) < $x >> という値を返します。 従って、perl に作ってほしいものは、0 から、必要な I と I との差 までの範囲の乱数です。 =begin original That is, to get a number between 10 and 15, inclusive, you want a random number between 0 and 5 that you can then add to 10. =end original つまり、10 から 15 の範囲の値(両端を含む) を得るためには、 0 から 5 の範囲の乱数を求めて、それに 10 を加えます。 my $number = 10 + int rand( 15-10+1 ); =begin original Hence you derive the following simple function to abstract that. It selects a random integer between the two given integers (inclusive), For example: C. =end original 従って、これを抽象化するために以下のサンプル関数を導き出します。 これは与えられた二つの整数を含む範囲のランダムな整数を選択します。 例えば: C sub random_int_between { my($min, $max) = @_; # Assumes that the two arguments are integers themselves! return $min if $min == $max; ($min, $max) = ($max, $min) if $min > $max; return $min + int rand(1 + $max - $min); } =head1 Data: Dates (データ:日付) =head2 How do I find the day or week of the year? (その年の何日目であるかを知るには?) =begin original The localtime function returns the day of the year. Without an argument localtime uses the current time. =end original localtime 関数はその年の何日目であるかを返します。 引数なしの localtime は現在時刻を使います。 $day_of_year = (localtime)[7]; =begin original The C module can also format a date as the day of the year or week of the year. =end original C モジュールも日付をその年の何日目か、または何週目かに整形します。 use POSIX qw/strftime/; my $day_of_year = strftime "%j", localtime; my $week_of_year = strftime "%W", localtime; =begin original To get the day of year for any date, use C's C to get a time in epoch seconds for the argument to localtime. =end original 任意の日付に対してその年の何日目かを得るには、localtime の引数から 紀元からの秒数を求めるために、C の C を使います。 use POSIX qw/mktime strftime/; my $week_of_year = strftime "%W", localtime( mktime( 0, 0, 0, 18, 11, 87 ) ); =begin original The C module provides two functions to calculate these. =end original C モジュールはこれらを計算する二つの関数を提供します。 use Date::Calc; my $day_of_year = Day_of_Year( 1987, 12, 18 ); my $week_of_year = Week_of_Year( 1987, 12, 18 ); =head2 How do I find the current century or millennium? (現在の世紀や千年紀を知るには?) =begin original Use the following simple functions: =end original 以下の単純な関数を使ってください: sub get_century { return int((((localtime(shift || time))[5] + 1999))/100); } sub get_millennium { return 1+int((((localtime(shift || time))[5] + 1899))/1000); } =begin original On some systems, the C module's C function has been extended in a non-standard way to use a C<%C> format, which they sometimes claim is the "century". It isn't, because on most such systems, this is only the first two digits of the four-digit year, and thus cannot be used to reliably determine the current century or millennium. =end original システムによっては、C モジュールの C 関数が 非標準の方法で C<%C> フォーマット("century"だと主張されることがあります)を 使うように拡張されているかもしれません。 これは世紀ではありません。 なぜならこのようなシステムのほとんどでは、 これは 4 桁の年の上位 2 桁を示しているだけなので、 現在の世紀や千年紀を決定する信頼できる方法ではありません。 =head2 How can I compare two dates and find the difference? (二つの日付文字列を比較するには?) =begin original (contributed by brian d foy) =end original (brian d foy によって寄贈されました) =begin original You could just store all your dates as a number and then subtract. Life isn't always that simple though. If you want to work with formatted dates, the C, C, or C modules can help you. =end original 日付を単に数値として保管して、それから引き算することもできます。 しかし、人生はいつもこんな風に単純とは限りません。 フォーマットされた日付に対して作業したい場合は、 C, C, C といったモジュールが 助けになるかもしれません。 =head2 How can I take a string and turn it into epoch seconds? (文字列を受け取って、それを紀元からの経過秒数に変換するには?) =begin original If it's a regular enough string that it always has the same format, you can split it up and pass the parts to C in the standard C module. Otherwise, you should look into the C and C modules from CPAN. =end original もしそれが常に同じ書式である十分に標準的な文字列であれば、それを分割して、 その部分部分を標準の Time::Local モジュールの C に渡せます。 さもなければ、CPAN にある C モジュールと C モジュールを見るべきでしょう。 =head2 How can I find the Julian Day? (ユリウス日を求めるには?) =begin original (contributed by brian d foy and Dave Cross) =end original (brian d foy と Dave Cross によって寄贈されました) =begin original You can use the C module available on CPAN. Ensure that you really want to find a Julian day, though, as many people have different ideas about Julian days. See http://www.hermetic.ch/cal_stud/jdn.htm for instance. =end original CPAN にある C モジュールが使えます。 しかし、本当にユリウス日がほしいのか確認してください; 多くの人々がユリウス日に関して異なる考え方を持っています。 例としては、http://www.hermetic.ch/cal_stud/jdn.htm を参照してください。 =begin original You can also try the C module, which can convert a date/time to a Julian Day. =end original 日付・時刻をユリウス日に変換できる、C モジュールを試すことも できます。 $ perl -MDateTime -le'print DateTime->today->jd' 2453401.5 =begin original Or the modified Julian Day =end original あるいは準ユリウス日にも変換できます: $ perl -MDateTime -le'print DateTime->today->mjd' 53401 =begin original Or even the day of the year (which is what some people think of as a Julian day) =end original あるいは年の何日目か(これがユリウス日だと考える人もいます)にも変換できます: $ perl -MDateTime -le'print DateTime->today->doy' 31 =head2 How do I find yesterday's date? (昨日の日付を得るには?) =begin original (contributed by brian d foy) =end original (brian d foy によって寄贈されました) =begin original Use one of the Date modules. The C module makes it simple, and give you the same time of day, only the day before. =end original Date モジュールの一つを使いましょう。 C モジュールは単純で、前日の同じ時刻を返します。 use DateTime; my $yesterday = DateTime->now->subtract( days => 1 ); print "Yesterday was $yesterday\n"; =begin original You can also use the C module using its C function. =end original C モジュールの C 関数を使うこともできます。 use Date::Calc qw( Today_and_Now Add_Delta_DHMS ); my @date_time = Add_Delta_DHMS( Today_and_Now(), -1, 0, 0, 0 ); print "@date_time\n"; =begin original Most people try to use the time rather than the calendar to figure out dates, but that assumes that days are twenty-four hours each. For most people, there are two days a year when they aren't: the switch to and from summer time throws this off. Let the modules do the work. =end original ほとんどの人は日付を計算するのにカレンダーではなく時刻を使おうとしますが、 これは 1 日が 24 時間であることを仮定しています。 ほとんどの人々にとって、そうではない日が 2 日あります: 夏時間が始まる日と終わる日はこれを狂わせます。 この作業はモジュールにさせましょう。 =head2 Does Perl have a Year 2000 problem? Is Perl Y2K compliant? (Perl には 2000 年問題があるのですか? Perl は 2000 年対応ですか?) =begin original Short answer: No, Perl does not have a Year 2000 problem. Yes, Perl is Y2K compliant (whatever that means). The programmers you've hired to use it, however, probably are not. =end original 短い答: いいえ、Perl には 2000 年問題はありません。 はい、Perl は(どのような意味でも) 2000 年対応です。 ただし、あなたの雇っているプログラマがそうでないように 使っているなら 2000 年問題はあります。 =begin original Long answer: The question belies a true understanding of the issue. Perl is just as Y2K compliant as your pencil--no more, and no less. Can you use your pencil to write a non-Y2K-compliant memo? Of course you can. Is that the pencil's fault? Of course it isn't. =end original 長い答: この質問は物事の理解を誤っています。 Perl はあなたの鉛筆と同じぐらいに Y2K 対応です。 それ以上でもそれ以下でもありません。 あなたの鉛筆を使って Y2K 対応でないメモを書けますか? もちろん書けます。 それは鉛筆のせいですか? もちろん違います。 =begin original The date and time functions supplied with Perl (gmtime and localtime) supply adequate information to determine the year well beyond 2000 (2038 is when trouble strikes for 32-bit machines). The year returned by these functions when used in a list context is the year minus 1900. For years between 1910 and 1999 this I to be a 2-digit decimal number. To avoid the year 2000 problem simply do not treat the year as a 2-digit number. It isn't. =end original Perl に組み込みの日付・時刻関数(gmtimeとlocaltime)は 2000 年を越えた年も区別するために必要な情報を提供しています (32 ビットマシンをトラブルが直撃するのは2038年です)。 これらの関数がリストコンテキストで使われたときに返す年数は 実際の年から 1900 を引いた値です。1910 年から 1999 年は このやり方では B<たまたま> 二桁の数値となります。 2000 年問題を避けるには、年を二桁で扱わないようにします。 =begin original When gmtime() and localtime() are used in scalar context they return a timestamp string that contains a fully-expanded year. For example, C<$timestamp = gmtime(1005613200)> sets $timestamp to "Tue Nov 13 01:00:00 2001". There's no year 2000 problem here. =end original gmtime() や localtime() は、スカラコンテキストで呼び出された場合には 完全な年を含んでいるタイムスタンプ文字列を返します。 たとえば、C<$timestamp = gmtime(1005613200)> は $timestamp に "Tue Nov 13 01:00:00 2001" をセットします。 ここには 2000 年問題はありません。 =begin original That doesn't mean that Perl can't be used to create non-Y2K compliant programs. It can. But so can your pencil. It's the fault of the user, not the language. At the risk of inflaming the NRA: "Perl doesn't break Y2K, people do." See http://www.perl.org/about/y2k.html for a longer exposition. =end original このことは、Perl で 2000 年問題を起こすようなプログラムを作るのに 使えないということではありません。あなたの使う鉛筆も そうであるように。つまり、言語にまつわるミスではなく、使う人の 間違いであるということです。 NRA を刺激するかもしれませんが、 「Perl は 2000 年問題を打ち破らない。人が打ち破るのだ。」ということです。 詳しい説明は http://www.perl.org/about/y2k.html を参照してください。 =head1 Data: Strings (データ: 文字列) =head2 How do I validate input? (入力を検査するには?) =begin original (contributed by brian d foy) =end original (brian d foy によって寄贈されました) =begin original There are many ways to ensure that values are what you expect or want to accept. Besides the specific examples that we cover in the perlfaq, you can also look at the modules with "Assert" and "Validate" in their names, along with other modules such as C. =end original 値があなたの予測している、または受け入れたいものであることを保証するには 多くの方法があります。 perlfaq でカバーする特定の例の他に、名前に "Assert" や "Validate" がある モジュールや、C のようなその他のモジュールを 見ることもできます。 =begin original Some modules have validation for particular types of input, such as C, C, C, and C. =end original C, C, C, C のように、特定の種類の入力を検査するための モジュールもあります。 =head2 How do I unescape a string? (文字列のアンエスケープ (unescape)をするには?) =begin original It depends just what you mean by "escape". URL escapes are dealt with in L. Shell escapes with the backslash (C<\>) character are removed with =end original それはあなたのいう「エスケープ」がなんであるかによります。 URL のエスケープは L で扱っています。 バックスラッシュによるシェルエスケープは以下のようにして取り除きます: s/\\(.)/$1/g; =begin original This won't expand C<"\n"> or C<"\t"> or any other special escapes. =end original これは C<\n> だとか C<\t>、あるいはその他の特殊なエスケープを展開しません。 =head2 How do I remove consecutive pairs of characters? (キャラクタの連続した組を取り除くには?) =begin original (contributed by brian d foy) =end original (brian d foy によって寄贈されました) =begin original You can use the substitution operator to find pairs of characters (or runs of characters) and replace them with a single instance. In this substitution, we find a character in C<(.)>. The memory parentheses store the matched character in the back-reference C<\1> and we use that to require that the same thing immediately follow it. We replace that part of the string with the character in C<$1>. =end original 文字の組(または文字の並び)を探して、それを一つの実体に置き換えるには 置換演算子が使えます。 この置換で、C<(.)> で一文字が見付かります。 記憶用のかっこはマッチングした文字を後方参照 C<\1> に保管し、 同じ文字を直後に要求するために使います。 文字列の一部を C<$1> にある文字で置き換えます。 s/(.)\1/$1/g; =begin original We can also use the transliteration operator, C. In this example, the search list side of our C contains nothing, but the C option complements that so it contains everything. The replacement list also contains nothing, so the transliteration is almost a no-op since it won't do any replacements (or more exactly, replace the character with itself). However, the C option squashes duplicated and consecutive characters in the string so a character does not show up next to itself =end original 文字変換演算子 C も使えます。 この例では、C の検索リスト側は何も入っていませんが、C オプションが ついているので全てが含まれます。 置き換えリスト側にも何も入っていないので、文字変換はほとんど何もしません (より厳密には、文字はその文字自身に置き換えられます)。 しかし、C オプションは文字列中の重複していて連続した文字を 1 文字に 短縮するので、次に同じ文字がある文字は表示されません: my $str = 'Haarlem'; # in the Netherlands $str =~ tr///cs; # Now Harlem, like in New York =head2 How do I expand function calls in a string? (文字列中にある関数呼び出しを展開するには?) =begin original (contributed by brian d foy) =end original (brian d foy によって寄贈されました) =begin original This is documented in L, and although it's not the easiest thing to read, it does work. In each of these examples, we call the function inside the braces used to dereference a reference. If we have more than one return value, we can construct and dereference an anonymous array. In this case, we call the function in list context. =end original これは L に文書化されていて、もっとも読みやすいものでは ありませんが、動きます。 これらの例のそれぞれにおいて、大かっこの内側の関数はリファレンスを デリファレンスするために呼び出します。 もし複数の返り値がある場合、無名配列を構築して、デリファレンスします。 この場合、関数をリストコンテキストで呼び出します。 print "The time values are @{ [localtime] }.\n"; =begin original If we want to call the function in scalar context, we have to do a bit more work. We can really have any code we like inside the braces, so we simply have to end with the scalar reference, although how you do that is up to you, and you can use code inside the braces. Note that the use of parens creates a list context, so we need C to force the scalar context on the function: =end original スカラコンテキストで関数を呼び出したい場合、もう少し作業が必要です。 実際に置きたいどんなコードでも中かっこの中に置けるので、 (それをどのようにするかはあなた次第で、中かっこのなかのコードを使えますが) 単にスカラリファレンスで終了する必要があります。 かっこはリストコンテキストを作成するので、関数内でスカラコンテキストを 強制するために C が必要であることに注意してください: print "The time is ${\(scalar localtime)}.\n" print "The time is ${ my $x = localtime; \$x }.\n"; =begin original If your function already returns a reference, you don't need to create the reference yourself. =end original 関数がすでにリファレンスを返す場合、自分でリファレンスを作る必要は ありません。 sub timestamp { my $t = localtime; \$t } print "The time is ${ timestamp() }.\n"; =begin original The C module can also do a lot of magic for you. You can specify a variable name, in this case C, to set up a tied hash that does the interpolation for you. It has several other methods to do this as well. =end original C モジュールもまたあなたのために多くの魔法を使います。 展開を行う tie されたハッシュを設定するための変数名(この場合は C)を 指定できます。 同じようにこれを行うその他のいくつかのメソッドを持っています。 use Interpolation E => 'eval'; print "The time values are $E{localtime()}.\n"; =begin original In most cases, it is probably easier to simply use string concatenation, which also forces scalar context. =end original ほとんどの場合、文字列連結を使ってスカラコンテキストに強制するほうが おそらくより簡単です。 print "The time is " . localtime() . ".\n"; =head2 How do I find matching/nesting anything? (何かがマッチしている/ネストしているということを検出するには?) =begin original This isn't something that can be done in one regular expression, no matter how complicated. To find something between two single characters, a pattern like C will get the intervening bits in $1. For multiple ones, then something more like C would be needed. But none of these deals with nested patterns. For balanced expressions using C<(>, C<{>, C<[> or C<< < >> as delimiters, use the CPAN module Regexp::Common, or see L. For other cases, you'll have to write a parser. =end original これは一つの正規表現で解決できないほどの複雑な問題なのです。 単一のキャラクター二つに囲まれた何かを見つけだすには、 C といったパターンを使えば $1 に検査の結果が得られるでしょう。 複数キャラクターに囲まれたものの場合は、 C のようなパターンが必要となるでしょう。 しかし、ネストしたパターンを扱うようなものはありませんし、できません。 C<(>, C<{>, C<[>, C<< < >> のいずれかのバランス表現をデリミタとして 使っている場合、CPAN にある Regexp::Common モジュールを使うか、 L を参照してください。 その他の場合では、パーサーを書く必要があります。 =begin original If you are serious about writing a parser, there are a number of modules or oddities that will make your life a lot easier. There are the CPAN modules C, C, and C; and the C program. Starting from perl 5.8 the C is part of the standard distribution. =end original もしまじめにパーザを作ろうと考えているのなら、 それを手助けしてくれるようなモジュールやその他のプログラムがあります。 CPAN には C, C, C がありますし、C プログラムもあります。 perl 5.8 から、C は標準配布の一部になりました。 =begin original One simple destructive, inside-out approach that you might try is to pull out the smallest nesting parts one at a time: =end original 単純で破壊的な inside-out アプローチもあります。 これは以下のようにして一度に最小のネスト部分を取り出そうというものです。 while (s/BEGIN((?:(?!BEGIN)(?!END).)*)END//gs) { # do something with $1 } =begin original A more complicated and sneaky approach is to make Perl's regular expression engine do it for you. This is courtesy Dean Inada, and rather has the nature of an Obfuscated Perl Contest entry, but it really does work: =end original より複雑で巧妙なやり方に Perl の正規表現エンジンを使うというものがあります。 これは Dean Inada によるもので Obfuscated Perl コンテストに エントリされるような代物ですが、正しく働きます: =begin original # $_ contains the string to parse # BEGIN and END are the opening and closing markers for the # nested text. =end original # $_ には解析対象の文字列があります # BEGINとENDはネストしたテキストの開始と終了とを行います。 @( = ('(',''); @) = (')',''); ($re=$_)=~s/((BEGIN)|(END)|.)/$)[!$3]\Q$1\E$([!$2]/gs; @$ = (eval{/$re/},$@!~/unmatched/i); print join("\n",@$[0..$#$]) if( $$[-1] ); =head2 How do I reverse a string? (文字列をひっくり返すには?) =begin original Use C in scalar context, as documented in L. =end original L で説明されているように、スカラコンテキストで C を使います。 $reversed = reverse $string; =head2 How do I expand tabs in a string? (文字列中にあるタブを展開するには?) =begin original You can do it yourself: =end original 以下のようにしてできます: 1 while $string =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e; =begin original Or you can just use the C module (part of the standard Perl distribution). =end original あるいは、ただ単に C モジュール(標準 Perl 配布キットの一部です)を 使ってもできます。 use Text::Tabs; @expanded_lines = expand(@lines_with_tabs); =head2 How do I reformat a paragraph? (段落を整形するには?) =begin original Use C (part of the standard Perl distribution): =end original C (標準 Perl 配布キットの一部です)を使います。 use Text::Wrap; print wrap("\t", ' ', @paragraphs); =begin original The paragraphs you give to C should not contain embedded newlines. C doesn't justify the lines (flush-right). =end original C に与える段落には埋め込みの改行があってはいけません。 C は行を均等割り付けしません(左寄せします)。 =begin original Or use the CPAN module C. Formatting files can be easily done by making a shell alias, like so: =end original または CPAN の C モジュールを使ってください。 ファイルの整形は以下のようにシェルエイリアスを作ることによって 簡単に実現できます: alias fmt="perl -i -MText::Autoformat -n0777 \ -e 'print autoformat $_, {all=>1}' $*" =begin original See the documentation for C to appreciate its many capabilities. =end original その多くの能力を評価するために、C の文書を 参照してください。 =head2 How can I access or change N characters of a string? (文字列の最初の N 文字にアクセスしたり、それを変更するには?) =begin original You can access the first characters of a string with substr(). To get the first character, for example, start at position 0 and grab the string of length 1. =end original 文字列の先頭の文字へは substr() でアクセスできます。 例えば、最初の文字を得るには、位置 0 から始めて、長さ 1 の文字列を 取得します。 $string = "Just another Perl Hacker"; $first_char = substr( $string, 0, 1 ); # 'J' =begin original To change part of a string, you can use the optional fourth argument which is the replacement string. =end original 文字列の一部を変換するために、省略可能な 4 番目の引数として置き換える 文字列を指定できます。 substr( $string, 13, 4, "Perl 5.8.0" ); =begin original You can also use substr() as an lvalue. =end original substr() を左辺値として使うこともできます。 substr( $string, 13, 4 ) = "Perl 5.8.0"; =head2 How do I change the Nth occurrence of something? (何かの N 番目のものを変更するには?) =begin original You have to keep track of N yourself. For example, let's say you want to change the fifth occurrence of C<"whoever"> or C<"whomever"> into C<"whosoever"> or C<"whomsoever">, case insensitively. These all assume that $_ contains the string to be altered. =end original 自分で N 番目の記録を取る必要があります。 例えば、(大小文字の違いを無視して) 5 番目に現れた C<"whoever"> か C<"whomever"> を C<"whosoever"> か C<"whomsoever"> に変更したいと考えているとしましょう。 以下は全て $_ に変更したい文字列が入っているものとします。 $count = 0; s{((whom?)ever)}{ ++$count == 5 # is it the 5th? ? "${2}soever" # yes, swap : $1 # renege and leave it there }ige; =begin original In the more general case, you can use the C modifier in a C loop, keeping count of matches. =end original もっと一般的なケースでは、C ループの中で C 修飾子を使ってマッチの数を数えることもできます。 $WANT = 3; $count = 0; $_ = "One fish two fish red fish blue fish"; while (/(\w+)\s+fish\b/gi) { if (++$count == $WANT) { print "The third fish is a $1 one.\n"; } } =begin original That prints out: C<"The third fish is a red one."> You can also use a repetition count and repeated pattern like this: =end original これは C<"The third fish is a red one."> のように出力します。 以下のようにパターンの繰り返し回数を指定するやり方もあります: /(?:\w+\s+fish\s+){2}(\w+)\s+fish/i; =head2 How can I count the number of occurrences of a substring within a string? (ある文字列の中に存在する部分文字列が何個あるのかを数えるには?) =begin original There are a number of ways, with varying efficiency. If you want a count of a certain single character (X) within a string, you can use the C function like so: =end original 様々な効率を持った、いろいろなやり方があります。 文字列中に存在しているある単一キャラクター (X) の数を数えたいのであれば、 C 関数を使って次のようにできます: $string = "ThisXlineXhasXsomeXx'sXinXit"; $count = ($string =~ tr/X//); print "There are $count X characters in the string"; =begin original This is fine if you are just looking for a single character. However, if you are trying to count multiple character substrings within a larger string, C won't work. What you can do is wrap a while() loop around a global pattern match. For example, let's count negative integers: =end original これは単一キャラクターを対象にするのであればちょうどいいものですが、 大きな文字列中の、複数キャラクターから構成される部分文字列の数を 数えようとしても、C はうまく動作しません。 ここで可能なのは、グローバルなパターンマッチを while() で囲んでしまうという ものです。たとえば、負の数を数えるのならこうします: $string = "-9 55 48 -2 23 -76 4 14 -44"; while ($string =~ /-\d+/g) { $count++ } print "There are $count negative numbers in the string"; =begin original Another version uses a global match in list context, then assigns the result to a scalar, producing a count of the number of matches. =end original もう一つのバージョンでは、リストコンテキストでグローバルマッチングを 使って、その結果をスカラに代入することで、マッチングした数を数えます。 $count = () = $string =~ /-\d+/g; =head2 How do I capitalize all the words on one line? (一行にあるすべての単語をキャピタライズするには?) =begin original To make the first letter of each word upper case: =end original 各単語の最初の文字を大文字にするにはこうします: $line =~ s/\b(\w)/\U$1/g; =begin original This has the strange effect of turning "C" into "C". Sometimes you might want this. Other times you might need a more thorough solution (Suggested by brian d foy): =end original これには、"C" を "C" にしてしまうような 妙な効果があります。 あなたがしたいのはこれでいいのかもしれません。 そうでないときには、以下のようにする必要があります (Brian d Foy の提案によります): $string =~ s/ ( (^\w) #at the beginning of the line | # or (\s\w) #preceded by whitespace ) /\U$1/xg; $string =~ s/([\w']+)/\u\L$1/g; =begin original To make the whole line upper case: =end original 行全体を大文字にするにはこうします: $line = uc($line); =begin original To force each word to be lower case, with the first letter upper case: =end original 全ての語を小文字にし、それぞれの語の最初の文字を大文字にするには こうします: $line =~ s/(\w+)/\u\L$1/g; =begin original You can (and probably should) enable locale awareness of those characters by placing a C pragma in your program. See L for endless details on locales. =end original プログラムの中に C を置くことによって、 これらのキャラクターがロカールを意識するようにできます (また、そうすべきです)。 ロカールに関する詳細は L を参照してください。 =begin original This is sometimes referred to as putting something into "title case", but that's not quite accurate. Consider the proper capitalization of the movie I, for example. =end original これは“title case”として扱われることがありますが、 それは正確なものではありません。 例えば映画のタイトルである I (邦題「博士の異常な愛情 または私は如何にして心配するのを止めて 水爆を愛するようになったか」) を考えてみましょう。 =begin original Damian Conway's L module provides some smart case transformations: =end original Damian Conway による L モジュールは、いくつかの 賢い大文字小文字変換を提供します: use Text::Autoformat; my $x = "Dr. Strangelove or: How I Learned to Stop ". "Worrying and Love the Bomb"; print $x, "\n"; for my $style (qw( sentence title highlight )) { print autoformat($x, { case => $style }), "\n"; } =head2 How can I split a [character] delimited string except when inside [character]? ((とある文字)の内側にある時を除き、(とある文字)で終端されている文字列を分割するには?) =begin original Several modules can handle this sort of parsing--C, C, C, and C, among others. =end original いくつかのモジュールがこのようなパースを扱います-- C, C, C, C などです。 =begin original Take the example case of trying to split a string that is comma-separated into its different fields. You can't use C because you shouldn't split if the comma is inside quotes. For example, take a data line like this: =end original カンマで分割された文字列を別々のフィールドに置くような例を 考えてみましょう。 ここで C を使うことはできません。 なぜなら、クォートの内側にあるカンマで分割すべきではないからです。 例えば以下のようなデータを考えてみましょう。 SAR001,"","Cimetrix, Inc","Bob Smith","CAM",N,8,1,0,7,"Error, Core Dumped" =begin original Due to the restriction of the quotes, this is a fairly complex problem. Thankfully, we have Jeffrey Friedl, author of I, to handle these for us. He suggests (assuming your string is contained in C<$text>): =end original クォートの制約のためにこれは実に複雑な問題です。 ありがたいことに、私たちには I の著者でもあり、 この問題を私たちのために扱ってくれる Jeffrey Friedl がいます。 彼の提案はこうです(文字列が C<$text> にあると仮定しています): @new = (); push(@new, $+) while $text =~ m{ "([^\"\\]*(?:\\.[^\"\\]*)*)",? # groups the phrase inside the quotes | ([^,]+),? | , }gx; push(@new, undef) if substr($text,-1,1) eq ','; =begin original If you want to represent quotation marks inside a quotation-mark-delimited field, escape them with backslashes (eg, C<"like \"this\"">. =end original クォーテーションマークで終端されたフィールドの中で クォーテーションマークを表現したいのならば、 それをバックスラッシュで(C<"like \"this\""> のように)エスケープしてください。 =begin original Alternatively, the C module (part of the standard Perl distribution) lets you say: =end original あるいは、C モジュール(標準 Perl 配布の一部です)を 使ってこうします: use Text::ParseWords; @new = quotewords(",", 0, $text); =head2 How do I strip blank space from the beginning/end of a string? (文字列の先頭や末尾にある空白を剥ぎ取るには?) =begin original (contributed by brian d foy) =end original (brian d foy によって寄贈されました) =begin original A substitution can do this for you. For a single line, you want to replace all the leading or trailing whitespace with nothing. You can do that with a pair of substitutions. =end original 置換を使うことで行えます。 1 行では、先頭か末尾のどちらかの空白全てを削除します。 2 つの置換でこれが行えます。 s/^\s+//; s/\s+$//; =begin original You can also write that as a single substitution, although it turns out the combined statement is slower than the separate ones. That might not matter to you, though. =end original これを 1 回の置換で書くこともできますが、組み合わせた文は分かれている 文よりも遅くなります。 しかし、それはあなたには問題がないかもしれません。 s/^\s+|\s+$//g; =begin original In this regular expression, the alternation matches either at the beginning or the end of the string since the anchors have a lower precedence than the alternation. With the C flag, the substitution makes all possible matches, so it gets both. Remember, the trailing newline matches the C<\s+>, and the C<$> anchor can match to the physical end of the string, so the newline disappears too. Just add the newline to the output, which has the added benefit of preserving "blank" (consisting entirely of whitespace) lines which the C<^\s+> would remove all by itself. =end original この正規表現において、アンカーは the alternation より低い優先順位を 持つので、the alternation は文字列の先頭か末尾にマッチングします。 C フラグが付いていることにより、可能な全てのマッチングについて置換が 行われるので、先頭と末尾の両方で行われます。 引き続く改行は C<\s+> にマッチングし、C<$> アンカーは文字列の物理的な 末尾にマッチングするので、改行も消えることを忘れないでください。 単に出力に改行を追加することで、C<^\s+> がすべて削除してしまう「空の」 (空白だけからなる)行を保存する利点が追加されます。 while( <> ) { s/^\s+|\s+$//g; print "$_\n"; } =begin original For a multi-line string, you can apply the regular expression to each logical line in the string by adding the C flag (for "multi-line"). With the C flag, the C<$> matches I an embedded newline, so it doesn't remove it. It still removes the newline at the end of the string. =end original 複数行の文字列に対しては、C ("multi-line") フラグを追加することにより、 文字列中の論理行毎に正規表現を適用できます。 C フラグをつけると、C<$> 組み込まれた改行の I<前に> マッチングするので、 これを取り除けません。 文字列の末尾の改行は取り除けます。 $string =~ s/^\s+|\s+$//gm; =begin original Remember that lines consisting entirely of whitespace will disappear, since the first part of the alternation can match the entire string and replace it with nothing. If need to keep embedded blank lines, you have to do a little more work. Instead of matching any whitespace (since that includes a newline), just match the other whitespace. =end original 空白だけからなる文字列は、置換の最初の部分が文字列全体にマッチングして、 それを空文字列に置き換えてしまうので、消えてしまうことに注意してください。 もし組み込まれている空行を保存したいなら、さらにもう少し作業をする必要が あります。 全ての空白(改行を含みます)にマッチングさせる代わりに、単にその他の 空白にマッチングさせます。 $string =~ s/^[\t\f ]+|[\t\f ]+$//mg; =head2 How do I pad a string with blanks or pad a number with zeroes? (文字列に空白をパッディングしたり、数値にゼロをパッディングしたりするには?) =begin original In the following examples, C<$pad_len> is the length to which you wish to pad the string, C<$text> or C<$num> contains the string to be padded, and C<$pad_char> contains the padding character. You can use a single character string constant instead of the C<$pad_char> variable if you know what it is in advance. And in the same way you can use an integer in place of C<$pad_len> if you know the pad length in advance. =end original 以下に挙げる例で、C<$pad_len> はパッディングしたい文字列の長さです。 C<$text> や C<$num> は文字列にパッディングの対象となる内容を保持していて、 C<$pad_char> がパッディングに使いたいキャラクターを保持しています。 やっていることがわかっているのなら、C<$pad_char> という変数の代わりに一 文字のキャラクター文字列を使うこともできます。 そして同様に、パッディングしたい長さが予め分かっているなら、 C<$pad_len> に整数値を指定することも出来ます。 =begin original The simplest method uses the C function. It can pad on the left or right with blanks and on the left with zeroes and it will not truncate the result. The C function can only pad strings on the right with blanks and it will truncate the result to a maximum length of C<$pad_len>. =end original 最も単純なやり方は C 関数を使うというものです。 この関数は文字列の左や右にパッディングを行ったり、0 を左に置いたりする ことができます。 C 関数は文字列の右側に空白でパッディングすることと、 結果の最大長を C<$pad_len> に切り詰めることだけができます。 # Left padding a string with blanks (no truncation): $padded = sprintf("%${pad_len}s", $text); $padded = sprintf("%*s", $pad_len, $text); # same thing # Right padding a string with blanks (no truncation): $padded = sprintf("%-${pad_len}s", $text); $padded = sprintf("%-*s", $pad_len, $text); # same thing # Left padding a number with 0 (no truncation): $padded = sprintf("%0${pad_len}d", $num); $padded = sprintf("%0*d", $pad_len, $num); # same thing # Right padding a string with blanks using pack (will truncate): $padded = pack("A$pad_len",$text); =begin original If you need to pad with a character other than blank or zero you can use one of the following methods. They all generate a pad string with the C operator and combine that with C<$text>. These methods do not truncate C<$text>. =end original 空白やゼロ以外のキャラクターでパッディングを行いたいのであれば、 以下に挙げるやり方を使うことができます。これらは全て パッディング文字列を C 修飾子で生成して C<$text> と結合します。 これらのメソッドは C<$text> を切り詰めません。 =begin original Left and right padding with any character, creating a new string: =end original 任意のキャラクターによる左詰めと右詰めを行い、新しい文字列を作ります: $padded = $pad_char x ( $pad_len - length( $text ) ) . $text; $padded = $text . $pad_char x ( $pad_len - length( $text ) ); =begin original Left and right padding with any character, modifying C<$text> directly: =end original 任意のキャラクターによる左詰めと右詰めを行い、C<$text> を直接変更します: substr( $text, 0, 0 ) = $pad_char x ( $pad_len - length( $text ) ); $text .= $pad_char x ( $pad_len - length( $text ) ); =head2 How do I extract selected columns from a string? (文字列から選択されたカラムを取り出すには?) =begin original (contributed by brian d foy) =end original (brian d foy によって寄贈されました) =begin original If you know where the columns that contain the data, you can use C to extract a single column. =end original データが含まれている桁が分かっているなら、単一の桁を展開するために C が使えます。 my $column = substr( $line, $start_column, $length ); =begin original You can use C if the columns are separated by whitespace or some other delimiter, as long as whitespace or the delimiter cannot appear as part of the data. =end original 桁が空白やその他のデリミタで分けられていて、データの一部としては 空白やデリミタが現れないなら、C が使えます。 my $line = ' fred barney betty '; my @columns = split /\s+/, $line; # ( '', 'fred', 'barney', 'betty' ); my $line = 'fred||barney||betty'; my @columns = split /\|/, $line; # ( 'fred', '', 'barney', '', 'betty' ); =begin original If you want to work with comma-separated values, don't do this since that format is a bit more complicated. Use one of the modules that handle that fornat, such as C, C, or C. =end original カンマ区切りの値(CSV)を扱いたい場合は、フォーマットが少し複雑なので これはしないで下さい。 C, C, C のような、この フォーマットを扱うためのモジュールの一つを使ってください。 =begin original If you want to break apart an entire line of fixed columns, you can use C with the A (ASCII) format. by using a number after the format specifier, you can denote the column width. See the C and C entries in L for more details. =end original 固定桁の行全体を分解したいなら、C の A (ASCII) フォーマットが 使えます。 フォーマット指定子の後に数値をつけることで、桁数を指定できます。 更なる詳細については L の C と C の項目を 参照してください。 my @fields = unpack( $line, "A8 A8 A8 A16 A4" ); =begin original Note that spaces in the format argument to C do not denote literal spaces. If you have space separated data, you may want C instead. =end original C のフォーマット引数での空白はリテラルな空白を意味しないことに 注意してください。 もし空白で区切られたデータがあるなら、代わりに C を使ったほうが いいかもしれません。 =head2 How do I find the soundex value of a string? (文字列の soundex 値を見つけるには?) =begin original (contributed by brian d foy) =end original (brian d foy によって寄贈されました) =begin original You can use the Text::Soundex module. If you want to do fuzzy or close matching, you might also try the C, and C, and C modules. =end original Text::Soundex モジュールが使えます。 あいまいマッチングや近傍マッチングを行いたいなら、 C, C, C といった モジュールを試すのも良いでしょう。 =head2 How can I expand variables in text strings? (テキスト文字列の中にある変数を展開するには?) =begin original (contributed by brian d foy) =end original (brian d foy によって寄贈されました) =begin original If you can avoid it, don't, or if you can use a templating system, such as C or C