
while(<GO>){
if($_ =~ /BOOK(.+)/){
print OUT "\n$1,";
}
#01234を見つけたら、一番最初の文字列を抜き出す
if($_ =~ /012345 (.+)(.+)(.+)(.+)(.+)(.+) /){
#その文字列の文末を削除
$data=(.+)
substr($data, -3, 2) = "";
print OUT "$1,";
}
}
close(OUT);
データ例
#####BOOK######
###################33##########################
012345 6.6666ppm 2.6asc 3.9asc GOOD 0 0
012345 1.6666pm 2.6asc 3.9asc NO 0 0
012345 6.6656pppm 2.6asc 3.9asc MIN 0 0
###################36##########################
012346 6.6666ppm 2.6asc 3.9asc GOOD 0 0
012346 1.6666ppm 2.6asc 3.9asc NO 0 0
012346 6.6656ppm 2.6asc 3.9asc MIN 0 0
上記のようなデータから一番左の文字列があったら、
一番最初の文字列を切り出し,文末を削除したいのですが、
作成したperlでは6.6666ppm 2.6asc 3.9asc まで切り出して且文末が削除できません。
どうかアドバイスをお願いします。
No.11ベストアンサー
- 回答日時:
>012345 6.6666ppm 2.6asc 3.9asc GOOD 0 0
>========= ====
>print OUT "$1,$2" if /^01234\d+\s+(-?[\d.]+)+\s+\d+\s+\d+s+(\d)/;
\d は数字を意味しますので、(\d+) では GOOD を捕捉することはできません。GOOD, NO, MIN
等の大文字だけの単語をを切り出すには、([A-Z]+) を使うことができます。\s (空白類) と
\S (空白以外) で行の構造にしたがって正規表現を組み立てると、捕捉することができます。
print OUT "$1,$2" if /^01234\d+\s+(-?[\d.]+)\S+\s+\S+\s+\S+\s+([A-Z]+)/;
また、途中を読み飛ばす次のような方法もあります。
print OUT "$1,$2" if /^01234\d+\s+(-?[\d.]+).*\b([A-Z]+)/;
この度は色々とありがとうございました。
もう少しアドバイスいただきたいのですが当初の疑問は解消できました。ありがとうございました。
No.10
- 回答日時:
No9 の回答に書き間違いがありました。
2行目の (-?[\w.]+) を (-?[\d.]+) に訂正します。ありがとうございます。
もうひとつアドバイスをいただきたく、よろしくお願いします。
・以下のように6.6666と合わせてGOODを出力したい時はどのように
すればよいですか?うまくいきません。
012345 6.6666ppm 2.6asc 3.9asc GOOD 0 0
========= ====
print OUT "$1,$2" if /^01234\d+\s+(-?[\d.]+)+\s+\d+\s+\d+s+(\d)/;
No.9
- 回答日時:
>1.抜き出す数字はマイナスのときはどうしたらよろしいでしょうか?
丸カッコの先頭に -? (- が0個または1個) を付けて、(-?[\w.]+)のようにすると抜き出すことができます。
>2.抜き出す数字の小数点以下が.0000のときはエクセルに出力するには?
エクセルを使ったことがないのでお答えできません。
>3.012345と012346のデータ間で改行をいれるにはどうしたらよろしいでしょうか?
# に囲まれた数字の行を利用することができると思います。次のコードは、先頭に数字そのものを
出力しています。
while (<GO>) {
print OUT "\n$1," if /^#+(\d+)#+/;
print OUT "$1," if /^01234\d+\s+(-?[\d.]+)/;
}
No.8
- 回答日時:
次のような簡単なコードで十分ではないかと思います。
ただ、BOOK に続く ######は意味のあるデータとは思えませんが?
while (<GO>) {
print OUT "\n$1," if /BOOK(.+)/;
print OUT "$1," if /^01234\d+\s+([\d.]+)/;
}
回答ありがとうございます。
追加でお聞きしたいことがあります。どうかお答えいただきたく、
よろしくお願いします。
1.抜き出す数字はマイナスのときはどうしたらよろしいでしょうか?
2.抜き出す数字の小数点以下が.0000のときはエクセルに出力するには?
3.012345と012346のデータ間で改行をいれるにはどうしたらよろしいでしょうか?
No.7
- 回答日時:
レコード(行)の先頭にある空白の扱いが微妙に違いますが、
フィールドの区切りに関して言えば、/ / は単にスペース一個という
解釈はされませんので、修正する必要はありません。
As a special case, specifying a PATTERN of space (' ') will
split on white space just as "split" with no arguments does.
Thus, "split(' ')" can be used to emulate awk's default
behavior, whereas "split(/ /)" will give you as many null
initial fields as there are leading spaces. A "split" on "/\s+/"
is like a "split(' ')" except that any leading whitespace
produces a null first field. A "split" with no arguments really
does a "split(' ', $_)" internally.
>後日譚。今思えば、この正規表現は全然へなちょこでした。
>[+-]?\d*?.?\d+
小数点を表すピリオドはエスケープする必要があるのではありませんか?
まあそういうことで。
No.6
- 回答日時:
4行目を
my ($num, $ppm) = split / +/;
とすれば、スペース1個以上で分割できます。なお、より一般的に空白文字で分割するには:
my ($num, $ppm) = split /\s+/;
こんな感じですね。
7行目
push @ppm, $ppm =~ /(\d?.?\d+)/;
にご注目ください。
後方参照のためのグループ化を使用した正規表現によるパターンマッチをリストコンテキストで評価すると、マッチした部分をリストで返します。
――つまり、カッコ内の正規表現にマッチしたやつが、@ppm に追加されるわけです。
ところで、「カッコ内の正規表現」って何でしょうか ?
\d?.?\d+
↑実はこれは、数字部分にマッチする正規表現です。
数字部分のみを抜き出して、@ppm に追加することができるわけです。
数字以降にいかなる文字列があろうとも、数字だけを抽出することができます。
後日譚。今思えば、この正規表現は全然へなちょこでした。
[+-]?\d*?.?\d+
せめてこれくらいはしないとダメですね。
No.5
- 回答日時:
間違えました。
正しくはこちらです。----------
my @ppm;
while (<GO>) {
my ($num, $ppm) = split / /;
next unless defined $num and defined $ppm;
next unless (substr $num, 0, 5) eq '01234';
push @ppm, $ppm =~ /(\d?.?\d+)/;
}
print OUT join ',', @ppm;
----------
7c7
< push @ppm, $ppm;
---
> push @ppm, $ppm =~ /(\d?.?\d+)/;
この回答への補足
回答ありがとうございます。
いつくか教えていただきたいことがあります。
(1)文末がpppmやpmの文字列も「my @ppm;」で抜けるのはなぜですか?
(2)下記のようにスペースが長いときもあるのですがそれも考慮して、
抜き出す方法はございますか?
012345 6.6666ppm 2.6asc 3.9asc GOOD 0 0
よろしくお願いいたします。
No.4
- 回答日時:
my @ppm;
while (<GO>) {
my ($num, $ppm) = split / /;
next unless defined $num and defined $ppm;
next unless (substr $num, 0, 5) eq '01234';
push @ppm, $ppm;
}
use 5.010000;
say OUT join ',', @ppm;
No.3
- 回答日時:
なんとなくこういうこと?
use strict;
use warnings;
use feature ':5.10';
open my $output, '>', 'sample.out';
while(my $line = <DATA>){
chomp $line;
if($line =~ /BOOK(.+)/){
print $output "\n$1,";
}
#01234を見つけたら、一番最初の文字列を抜き出す
if($line =~ /^01234/){
my ($num, $item1, $rest) = split / /, $line;
print $output "$item1,";
}
}
close $output;
__END__
#####BOOK######
###################33##########################
012345 6.6666ppm 2.6asc 3.9asc GOOD 0 0
012345 1.6666pm 2.6asc 3.9asc NO 0 0
012345 6.6656pppm 2.6asc 3.9asc MIN 0 0
###################36##########################
012346 6.6666ppm 2.6asc 3.9asc GOOD 0 0
012346 1.6666ppm 2.6asc 3.9asc NO 0 0
012346 6.6656ppm 2.6asc 3.9asc MIN 0 0
結果
######,6.6666ppm,1.6666pm,6.6656pppm,6.6666ppm,1.6666ppm,6.6656ppm,
最初に空行はいるとか、末尾にも','が付くってのはたぶんNGなんでしょうねえ。
んで、元データの#の行をじーっとみてみて
33,6.6666ppm,1.6666pm,6.6656pppm
34,6.6666ppm,1.6666ppm,6.6656ppm
とか
33,6.6666ppm,2.6asc,3.9asc
33,1.6666pm,2.6asc,3.9asc
33,6.6656pppm,2.6asc,3.9asc
34,6.6666ppm,2.6asc,3.9asc
34,1.6666ppm,2.6asc,3.9asc
34,6.6656ppm,2.6asc,3.9asc
みたいな結果がほしいのかなあと思わないでもないんですがどうなんでしょうか?
この回答への補足
説明がうまくなく、すいません。
出力イメージは以下のような感じです。
●出力イメージ
6.6666,1.6666,6.6656,6.6666,1.6666,6.6656,
No.2
- 回答日時:
スクリプトを見ても、正規表現がめちゃくちゃなので欲しい結果がどういうものかわかりません。
>012345 6.6656pppm 2.6asc 3.9asc MIN 0 0
>012346 6.6656ppm 2.6asc 3.9asc MIN 0 0
>上記のようなデータから一番左の文字列があったら、
>一番最初の文字列を切り出し,文末を削除したいのですが、
>作成したperlでは6.6666ppm 2.6asc 3.9asc まで切り出して且文末が削除できません。
一番左の文字列を切り出し文末を削除というのは
この例だと 6.6656ppm だけとれればいいんですか?
この回答への補足
>一番左の文字列を切り出し文末を削除というのは
>この例だと 6.6656ppm だけとれればいいんですか?
はい。それでppmを取りたいです。
簡単ですが、よろしくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) PowerQueryに詳しい方教えてください(Office365) 1 2022/07/24 21:11
- Excel(エクセル) 全角文字「ヴ」の半角文字「ヴ」への変換方法について 3 2022/11/05 12:07
- がん・心臓病・脳卒中 HPV 18型、軽度異形成について はじめにASC-USと診断され、HPV検査したところ18型に感染 10 2023/02/11 15:41
- PHP PHPの構文で間違えが分からない 5 2022/07/11 16:38
- PHP SQLとPHPの連結方法がわからないのでアドバイスお願い致します 1 2022/07/12 12:16
- その他(Microsoft Office) WordやExcelで英数字のみ半角または全角にしたい 6 2022/08/03 08:18
- その他(Microsoft Office) 英数字のみ全角から半角に変換 4 2023/07/28 14:48
- PHP php my adminより取り出したデータ表示 2 2022/06/15 11:56
- 婦人科の病気・生理 子宮頸がん検査結果のASC-USについて詳しいかたいますか? 質問したいです。 4 2022/10/21 19:59
- 婦人科の病気・生理 不正出血について 最近、ASC-US→HPV18型→軽度異形成→ASC-USと診断されたのですが診断 1 2023/02/20 15:07
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
テキストファイルで提出とは?
-
Perlでの文字列置換
-
畳み込みニューラルネットワー...
-
ファイルをディレクトリ分配の...
-
AI sisterとは、偽物の人ですか?
-
perlについての質問
-
cgiでサーバーにファイルを追加...
-
perl の open について教えてく...
-
Perl言語について。
-
アルファベットに付いて質問し...
-
#!/usr/bin/perlで書きだしたCG...
-
Perlのエラーについてご教授く...
-
perlのflock関数でロックをかけ...
-
bashスクリプト
-
ファイルアイコンの左下に緑の□...
-
perlプログラミング 空白行削除
-
perlでリテラル値はメモリにど...
-
perlで2次元配列をサブルーチ...
-
Perlで時間の計算
-
perlについて
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
テキストファイルで提出とは?
-
openした後、closeしないでプロ...
-
Perlのエラーについてご教授く...
-
INDIRECT 横に再度抽出したい
-
bashスクリプト
-
perlをバージョンアップしたら...
-
perlプログラミング 空白行削除
-
Wallpaper Engineでおすすめの...
-
perlのflock関数でロックをかけ...
-
Strawberry Perl for Windows ...
-
フローチャート 九九
-
perlについての質問
-
ターミナルで特定の文字と文字...
-
LinuxにおいてのPerlのプログラ...
-
P.Cのシングルチューナーとダブ...
-
PerlでUTF-8のファイルの文字列...
-
【超初心者】異なるディレクト...
-
perlで複数のファイルの処理に...
-
Perl 順位の重複
-
Perlで特定文字列から特定文字...
おすすめ情報