グッドデザイン賞を受賞したウォーターサーバー >>

お世話になっています。
正規表現の文字置換s///gを使って数字の3桁目に-を挿入したいですが、どうしたらいいのかわかりません。

どなたか教えていただけないでしょうか。

5770001

577-0001

にしたいのでしが…

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

A 回答 (3件)

試してないのですが


s/(.{3})(.*)/$1-$2/;
でよいはずです。

数字確定ならば\dでも可。
    • good
    • 0
この回答へのお礼

ありがとうございます。

汎用性があり、よかったです。

お礼日時:2004/10/14 11:53

既に解決済みのようですが、いろんな方法を知っておいて損はないので、別の例を1つ。



$zip = "5770001";
substr($zip, 3, 0) = "-";
print $zip;   # 577-0001

substr は左辺値(代入される側)にもでき、
  substr($string, $offset, $length) = $replace;
とすることで、$string の $offset バイト目から $length バイト分を $replace に置き換えることができます。
上の例はこれを利用し、$length を 0 とすることで挿入を行っています。

# Perl5.005以降なら、substr($string, $offset, $length, $replace) と書くこともできます。
    • good
    • 2

#!/usr/bin/perl



$c = '5770001';

$c =~ s/(\d\d\d)(\d\d\d\d)/$1\-$2/;
print $c. "\n";

これでどうでしょうか?
    • good
    • 1
この回答へのお礼

即レスありがとうございます。
試した結果うまく動きました。

お礼日時:2004/10/14 11:52

このQ&Aに関連する人気のQ&A

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

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

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

QPerlで特定行から特定行までを抜き出したい

皆さんのお知恵をお貸し頂ければ幸いです。

Perlで以下のようなことをしたいと考えています。
例えば、次のようなテキストファイルがあったとします。

example.log
==================================
aaaa
hogehoge
test
okok
perl
script
==================================

上記ファイルを読み込んで、「hogehoge」から「perl」の間に挟まれた行だけ抜き出したいのです。
イメージとしては、読み込んだファイルを配列に入れて、一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。

このような場合、どういう風にすればいいのでしょうか?
恐れ入りますが、ご教授頂ければ幸いです。

それでは、どうぞよろしくお願い致します。

Aベストアンサー

> 一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。

それでいいと思いますよ?これをそのままコード化すると、こんな感じでしょうか。(No.1さんのとはちょっと結果が違います。)

open FH, "example.log" or die $!;
$flag = 0;
while ($data = <FH>) {
  chomp $data;
  if  ($data eq "hogehoge") { $flag = 1 }
  elsif ($data eq "perl")    { $flag = 0 }
  elsif ($flag) { print "$data\n" }
}
close FH;

で、もっと略したいPerlな人だとこんな感じ。Perl独特の記法がふんだんに使われているので、勉強するには不向きかもしれませんが^^;

open FH, "example.log" or die $!;
while (<FH>) {
  print if /^hogehoge$/ .. /^perl$/ and !/^(?:hogehoge|perl)$/;
}
close FH;

※インデントに全角空白を使っているので、コピーする場合はタブなどに置換して下さい。

> 一行づつ読ませ、キーワード「hogehoge」が現れたらそこでフラグを立て、それ以降の行を表示し、キーワード「perl」が現れた時点で表示を止めるという処理になるのかな?と思っています。

それでいいと思いますよ?これをそのままコード化すると、こんな感じでしょうか。(No.1さんのとはちょっと結果が違います。)

open FH, "example.log" or die $!;
$flag = 0;
while ($data = <FH>) {
  chomp $data;
  if  ($data eq "hogehoge") { $flag = 1 }
  elsif ($data eq "perl")    { $fl...続きを読む

Q正規表現で何文字目から何文字目までのヒット

正規表現で何文字目から何文字目までのヒット

正規表現を使い、何文字目から何文字目までをヒットさせたいです。

例えば、下記の英字があります。

abcdefg

6文字目~7文字目をヒットさせたいです。この場合は、「fg」にヒットさせたいです。
先頭から何文字目までヒットというのならわかるのですが、特定の文字数から文字数まで
ヒットさせたいという場合、どのような正規表現を組めばいいのでしょうか?

Aベストアンサー

抜き出すんじゃなくてマッチさせたいとなると戻り読みですかね・・・肯定戻りも否定戻りも個人的に苦手なんですが

# サクラエディタ(ver 2.0.2.0) + bregonig.dll (ver 2.03)
(?<=^.{5}).{2}

QX行N番目の文字の置換(正規表現?)

生物学カテゴリーで同様の質問をさせていただきましたが、
回答を得ることができませんでしたので、ここで質問させていただきます。ここでの質問後に、生物学カテゴリーの質問は消去させていただきます。

私はPDB(protein date bank)ファイルを扱っております。
扱うソフトウェアによって書式が少しずつ変わっております。
そのため以下のような問題が生じております。

ここで、私が用いているソフトの出力形式では、
ATOM 1 N Met 001 -0.917 -70.390 0.893

というように出力されます(投稿時に連続する複数の空白が、一つの空白にまとめられてしまいます。ご了承ください。ちなみに、空白は左から6、2、3、3、…となっております。)。

別のソフトに入力するためには、
ATOM 1 N Met A 001 -0.917 -70.390 0.893
というように、Metと001の間に記号(前半の100行に対してはA、後半100行に対してはB)を入れる必要があります。
手動で一つ一つ入れる、というのも一つの方法ですが、時間がかかります。
現実的には、
1)linuxの文字変換コマンド(sedなど)を用いて、変換する。
2)pdbファイル変換ソフトを用いて、ファイルを変換する。
という方法が考えられます。
1)については、自分でやってもうまくいかず、
2)については、そのようなソフトがあるか探してみたのですが、見つけることができませんでした。pdbファイル、というのは別の種類のファイルを指すこともあるようで、google検索はうまくいきませんでした。

上記の変換を簡単に行う方法を御存知の方がいらっしゃれば、御教授お願いします。

生物学カテゴリーで同様の質問をさせていただきましたが、
回答を得ることができませんでしたので、ここで質問させていただきます。ここでの質問後に、生物学カテゴリーの質問は消去させていただきます。

私はPDB(protein date bank)ファイルを扱っております。
扱うソフトウェアによって書式が少しずつ変わっております。
そのため以下のような問題が生じております。

ここで、私が用いているソフトの出力形式では、
ATOM 1 N Met 001 -0.917 -70.390 0.893

というように出力されます(投稿時に連続...続きを読む

Aベストアンサー

行のフォーマットがすべて同じならば No2 の補足に書かれたのと似たような方法で
できるのではないかと思います。A (または B) の前後に必要な空白数によっては、
. の数や A (または B) の後ろの空白数で調整する必要があるかも知れません。

$ sed -e "1,100s/^......................./&A /; 101,$s/^......................./&B /" A.pdb > B

Q数値かどうかの判定方法

$aに代入されているものが数値かどうかを判定するにはどのようにしたらよいのでしょうか?

Aベストアンサー

$a =~ /^[0-9]*$/
上記の場合、*は「直前のパターンの0回以上の繰り返し」の意味なので、0から9がなくても、つまり$aが空でもマッチしてしまいます。
なので、
$a =~ /^[0-9]+$/
としましょう。
(+は「直前のパターンの1回以上の繰り返し」)
また、0-9は\dで表すこともできるので
$a =~ /^\d+$/
と書くこともできます。

Qgrepで検索文字列が完全一致した行だけ取り出す方法

grepの文字列検索で検索文字列が単語として、完全一致した行だけ取り出す方法はないでしょうか?

通常は
grep hoge hoge.txt

と打つと、hogeが含まれる行が出力されますが、今回は含まれる行ではなくて完全に文字列が一致した行だけ取り出したいのです。

例えばhoge.txtの中に
cc ghoge
kkl hogem
jjll hoge
という3行があったとしたら最後の行でhogeという文字が空白で区切られた行だけ取り出したいのです。

何かよい方法があれば教えてください

Aベストアンサー

-w オプションじゃだめですか?

参考URL:http://www.linux.or.jp/JM/html/GNU_grep/man1/grep.1.html

Q複数ファイルの読み込みについて

perl初心者です。

あるディレクトリから拡張子がdataであるファイルを全て読み込みたいのですが、方法がわかりません。
cshで書くと
foreach arg (*.data)
コマンド $arg

のようになりますが、perlだと
foreach $arg (@arg){
コマンド $arg

となりますよね?
引数がリストなのでよくわかりません。
そもそもperlではできないのでしょうか?


それともう一点ですが、ファイルオープンするときに
foreachループの中で
open(FILE, "$arg");
とすることは可能ですか?
上の質問と組み合わせて全てのファイルを開いて作業を行いたいので。

説明が下手ですいません。補足しますのでよろしくお願いします。

Aベストアンサー

while(<*.data>)
{
## $_には、*.DATAなファイル名が格納されている。
open(F,"$_"); ##openする。
while(<F>)
{
##読み出された内容が$_に格納されている。
print $_; ##出力してみる。
}
}

というのが最短コーディングです。

Qsedの置換文字に変数を使用したいのですが・・・

あるファイルの特定の文字を変換し、上書きをする処理を行いたいのですが、sedの置換文字に変数が渡せなくて困っています。

例:
X="a"
Y="b"
echo test.txt | sed 's/${X}/${Y/g}' >test.txt

sedでは置換文字に${X}といった変数を使用することはできないのでしょうか?

Aベストアンサー

' ・・・' で囲まれた中の$はそのままドルマークです。変数展開をするなら、'・・・'で囲んではいけません。

何も囲まないか、"・・・"で囲むかです。

Qシェルスクリプトでファイル内の数値文字列を数値として扱うには

失礼します。
シェルスクリプトでファイル内のテキスト(数値文字列)を取得して、それを使って計算するにはどうすれば良いでしょうか?

str:ファイル内のテキスト(数値文字列)

res=$(( $str + 1 ))

・エラー
")syntax error: invalid arithmetic operator (error token is "


よろしくお願いします。

Aベストアンサー

bashをご使用と判断して

res=$(( $str + 1 ))
ではなく、
res=$(( str + 1 ))
だと思います。

> exprもやってみたのですが、処理が遅くなるので使いません。
興味があって以下のシェルで検証してみました。

#!/bin/bash

str=1
i=0

echo 'Using $((str + 1))'
date '+%H:%M:%S.%N'

while [ $i -lt 10000 ]
do
str=$(( str + 1))
i=`expr $i + 1`
done

date '+%H:%M:%S.%N'

exit

$ ./test.sh
Using $((str + 1))
09:18:46.290418000
09:18:56.929345000
これをexprに書き換えたところ
$ ./test2.sh
Using expr
09:19:00.302748000
09:19:19.259990000

exprだと19秒ですが、$(( 演算 )) だと10秒程度なので、演算が多くなれば確かにexprは不利ですね。

bashをご使用と判断して

res=$(( $str + 1 ))
ではなく、
res=$(( str + 1 ))
だと思います。

> exprもやってみたのですが、処理が遅くなるので使いません。
興味があって以下のシェルで検証してみました。

#!/bin/bash

str=1
i=0

echo 'Using $((str + 1))'
date '+%H:%M:%S.%N'

while [ $i -lt 10000 ]
do
str=$(( str + 1))
i=`expr $i + 1`
done

date '+%H:%M:%S.%N'

exit

$ ./test.sh
Using $((str + 1))
09:18:46.290418000
09:18:56.929345000
これをe...続きを読む

QPerlで行頭にある文字が含まれている行を全部削除して詰めたい

perl初心者です。以下のようにデータがならんでいる時、
test111 aaaaaaaaabbbbbbbbcccccc
test112 aaaaccccabbbbbbbbcccccc
test113 aaaaccaaabbbbbbbbcccccc
test114 acccaaaaabbbbbbbbcccccc

test111 aacaaaaaabbbbbbbbcccccc
test112 accaaaaaabbbbbbbbcccccc
test113 aaacccaaabbbbbbbbcccccc
test114 aaaaaccaabbbbbbbbcccccc

test112の行だけ削除して、さらにそこを詰めたい時のスクリプトを作成しています。

途中からわかりません。
行を削除する関数が調べても見つからないのです。

#!/usr/bin/perl ;
open(IN, "test.doc") or die ;

open(OUT, ">testout.doc");

while(<IN>) {
chomp ;
if (/(\S+)/) {

$name = $1 ;

if ($name =~ /^test112(\S+)/) {
#ここでマッチさせて、一気に行を削除して、しかも行を詰めたいのですが

;

}
print OUT " \n" ;
}
}
close (IN) ;
close (OUT) ;

大変困っております。宜しくお願いします。

perl初心者です。以下のようにデータがならんでいる時、
test111 aaaaaaaaabbbbbbbbcccccc
test112 aaaaccccabbbbbbbbcccccc
test113 aaaaccaaabbbbbbbbcccccc
test114 acccaaaaabbbbbbbbcccccc

test111 aacaaaaaabbbbbbbbcccccc
test112 accaaaaaabbbbbbbbcccccc
test113 aaacccaaabbbbbbbbcccccc
test114 aaaaaccaabbbbbbbbcccccc

test112の行だけ削除して、さらにそこを詰めたい時のスクリプトを作成しています。

途中からわかりません。
行を削除する関数が調べても見つからないのです。

...続きを読む

Aベストアンサー

一致しなかったときのみ出力するということで、

while(<IN>){
unless(/^test112/){
print OUT;
}
}

更に簡単に書くと、
while(<IN>){
print OUT unless(/^test112/);
}
となります。

削除にこだわるなら、
while(<IN>){
s/^test112\s.+//;
print OUT;
}
あたりでしょうか。

もしくは、明示的に削除したいなら、
while(<IN>){
if(/^test112\s.+/){
$_ = "";
}
print OUT;
}
というふうに、カラの文字列を代入してやるのも、値を削除するときの常套手段ですね。

Qperlでcsvファイルを読む(ダブルコーテーション内カンマを無視したい)

perlでCSVファイルを読み込むスクリプトを作っています。

以下のようなCSVファイルがあります。

■CSVファイル
東京,よろしくお願いします。
大阪,はじめまして
九州,"5,000円でお願いします"

カンマで区切り、以下のようにすると、"5,000円"の部分が2つに分かれてしまいます。
($data1,$data2) = split(/,/,$all_data)

前後にダブルコーテーションがあった場合、中のカンマで区切らないような良い方法はないでしょうか?

環境:
Perl 5.8.5

Aベストアンサー

Text::ParseWords を使ってこんなのはどうですか。(例ではparse_lineを使っています)
もしquoteを残したければundefを1に変えてください。

use Text::ParseWords;

$" = "\t";
while (<DATA>) {
chomp;
my @words = &parse_line(',', undef, $_);
print "@words\n";
}

exit 0;
__DATA__
東京,よろしくお願いします。
大阪,はじめまして
九州,"5,000円でお願いします"


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング