人に聞けない痔の悩み、これでスッキリ >>

こんにちは
perlで特定の文字列からその後ろをすべて
削除したいのですが、うまくできなくて質問します。

Ex)123.12abc   ⇒123.12
012.123abc   ⇒012.123
123.1234|| ⇒123.1234

上記のようなデータの少数点までの数字の後ろにabc、||、半角、全角スペースなど文字列があります.
少数点までの数字の後ろの文字列すべてを削除したいですが、
特定の文字列からその後ろにある文字列全てを指定する方法(正規表現)はありませんでしょうか?

どうかご存知の方、教えてください!!
よろしくお願いいたします。

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

A 回答 (7件)

実験すればわかるけど, 可能なら「0 を足す」のが最も簡単ですぜ>#6.

    • good
    • 0

小数点付きの数字のみにしたい時は…


正規表現を /(\d+\.\d+)/ として $1にアクセスすればよくて

↓さんぷるこーど。 
===========================================
use strict;
use warnings;

while(<DATA>) {
chomp $_;
/(\d+\.\d+)/;
print "str:", $_, "\t-> ", $1 , "\n";
}

__DATA__
123.12abc
012.123abc
123.1234||

===========================================

整数のみも対応したければ
正規表現を /(\d+(\.\d+)?)/ として $1 にアクセスすればよいですね
↓さんぷるこーど。
===========================================
use strict;
use warnings;

while(<DATA>) {
chomp $_;
/(\d+(\.\d+)?)/;
print "str:", $_, "\t->",$1 , "\n";
}

__DATA__
123.12abc
012.123abc
123.1234||
===========================================
    • good
    • 0

こういう事ですね?



『文字列の先頭に、小数点付数値と解釈できる内容が入っています。 数値の一部とみなせない後続文字を削除したいです。』


if( $text !~ s/(\.\d*).*$/$1/s ) {
 die("入力がおかしいよ。\n");
}
print "$text を認識しました。\n";

# 小数点の無い整数には対応できません。
    • good
    • 0

例の 'abc' はどこにいったんだろう.


さておき, いろんな方法があって
・s/\|\|.*//; でつぶす
・m/(\d+\.\d*)\|\|/; で取り出す
・(split(/\|\|/))[0] で「最初の項目」を取り出す
・+0 で強制的に数値に変換する
などは思い付く.
    • good
    • 0

Tacosasさんがおっしゃっているように意味が分からないです。



最初では
>上記のようなデータの少数点までの数字の後ろにabc、||、半角、
>全角スペースなど文字列があります.
>少数点までの数字の後ろの文字列すべてを削除したいですが、
 なので、文面から最初の小数点「 . 」以降を消したいと読めます。

 が、 Tacosasさんへの補足では、
>'||'からその後ろまでを削除したいということです。
 小数点は何処へ行ってしまったのでしょうか?

 || と それ以降を削除でしたら、

$data =~ /^(.+)?\|\|/; ではどうでしょう。
    • good
    • 0

「少数点までの数字の後ろの文字列すべてを削除したい」って, 何がしたいのか理解できないんだけど.... 「少数点」は「小数点」のことだと思っていい?


でそうだとしても, 例えば一番上の 123.12abc の例だと, 「小数点までの数字」ってのは「123」だよね. 「その後ろの文字列すべてを削除」って言われても「1」より後ろなのか「2」より後ろなのか「3」より後ろなのかがわかんない. そして, 挙がっている例ではこのいずれでもない.
ということで, やりたいことを「正確に」書いてください.

この回答への補足

ごめんなさい。
質問がおかしかったです。
たとえば'123.1234||abcd'のような数値のあとに文字列がつく場合
'||abcd'を削除し、'123.1234'にしたいです。
数値の後に付く文字列は'||'のあとにくる文字列が'abcd'ではなく、
’edfg’’hijk’みたいに特定できないため、'||'からその後ろまでを
削除したいということです。

補足日時:2009/01/26 22:48
    • good
    • 0

小数点の前が必ず数字のみという条件で、その中の小数点以降を全て削除なら、



$data = '123.1234|| ⇒123.1234';

$data =~ /^(\d+)?\./;

print $1;

で、どうでしょうか。
    • good
    • 0

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

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

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

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

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

QPerlで文字列の切り出しをするには?

おせわになります。

Perlであるパターン間の文字列を取り出す方法はあるのでしょうか?例えば、"Monday<From>Thursday<To>Friday"という文字列の<From>~<To>間、つまり"Thursday"を取り出したいのですが、うまくいきません。
できればパイプでつないでいくために、以下のような正規表現でかければ最高なのですが…

echo 'Monday<From>Thursday<To>Friday' | perl -e '○○○○'

もう1週間以上ここではまっています。Perlってはまると長いです…

Aベストアンサー

こんな感じ

echo "Monday<From>Thursday<To>Friday" | perl -pe"s/.*<From>(.*)<To>.*/$1/g;"

Q正規表現について(最後にマッチした以降のデータ取得)

以下の文字列から、最後の「\」以降の文字列を取得する方法を
教えていただけますでしょうか。

D:\PROGRAM\ANALYZE\LAN\data0123.dat

この文字列から、「data0123.dat」を取り出したい。
「data0123.dat」の部分は、拡張子含めていろいろ変わります。

よろしくお願いいたします。

Aベストアンサー

もっとスマートな式があるかもしれませんが
my $S = 'D:\PROGRAM\ANALYZE\LAN\data0123.dat';
## 正規表現
$S =~ m/.*\\([^\\]+)$/;
print $1;
ただし、ファイルパスを見るとDOS(Windows)環境のようですので環境はShift-JIS。
全角文字が混ざった場合には正規表現が正常動作する保障がありません。
正規表現の練習なら良いのですがこの程度の処理なら組み込み関数使った処理のほうが効率が良いと思います。
## 組み込み関数
print substr($S,rindex($S,"\\")+1);
ほかにも書き方はあります。

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...続きを読む

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;
}
というふうに、カラの文字列を代入してやるのも、値を削除するときの常套手段ですね。

Q現在のディレクトリパスを取得するには!?

perlにて現在のディレクトリパスを取得するにはどのようにすればいいのでしょうか?
モジュールをつかってcwd()で取得できるようなのですが、モジュールが入っていないサーバでも動くようにしたいのですがうまくできません・・・
どなたかご存知でしたら教えてください。

Aベストアンサー

if($^O eq "MSWin32"){
$cwd=`cd`;
} else {
$cwd=`pwd`;
}
print $cwd;
--------------
ぐらいでいいんじゃないでしょうか

Q一番後ろのスラッシュ以降を削除する

お世話になります。Perlで
$URL=$in{'URL'};
でHTMLフォームからホームページアドレスを取得するとします。

これが
http://yahoo.co.jp/index.html なら
http://yahoo.co.jp/ のみに

http://yahoo.co.jp/nanka/toarru.html なら
http://yahoo.co.jp/nanka/ のみに

もちろん
http://yahoo.co.jp/ ならそのままに
$URLの値を変更したいのですが、どうしたらよいのでしょう。
サンプルコードなどで解説お願いします。

Aベストアンサー

こんなんでいいと思いますよ

$URL = "http://aaa.bbb.ccc/aaaa/bbbb/";
$aaa = substr($URL, 0, rindex($URL,"/")+1);

QPerlで変数を使用した置換ができない

ファイル内の「1 2 3 4 5」などの数字の箇所を、「1回 2回 3回 4回 5回」のように、「回」をつけた形に変えることを考えています。
以下のようなスクリプトを書きましたが、うまくいきません。

# 「$search_replace」の参照先のテキストファイルの内容
(\d) タブ記号 $1回


EOF

# 問題のスクリプト(一部)
chomp($search_replace);
(my $search, my $replace) = split(/\t/, $search_replace);
$string[$i+1] =~ s/$search/$replace/g; #ここが問題と思われる箇所

ほしい結果は右のとおり。「1回 2回 3回 4回 5回」
現実の結果は右のとおり。「$1回 $1回 $1回 $1回 $1回」

置換文字列の$1の部分がうまく展開(?)できないようです。
どうすればよいか、ご教示ください。

Aベストアンサー

正規表現の置換部はダブルクォート文字列と同様に評価されるので、次の2つの文は同じように機能します。質問のケースでは、変数を2重に置き換えなければならないので、明示的にダブルクォートが必要になります。

$string[$i+1] =~ s/$search/$1回/g;
$string[$i+1] =~ s/$search/"$1回"/eg;

Q文字列の ' aaa"bbbccc"ddd' から"で囲まれた部分を抜き出したい

こんにちは。
タイトルの通りなのですが

$test = 'aaa="bbbccc"ddd';
のbbbcccだけを抜き出したいので、

if ($test =~ /aaa=\"(.+)\"/) {
$test= $1;
}


と正規表現を利用して実行してみましたがうまく動作しません。

確定してるのは aaa="この間の文字列"の形で、
aaa=ダブルコーテーション ダブルコーテーション
は固定なのです。

そのようにな文字列から特定の個所を抜き出すように実装するには
どのようにすればよろしいのでしょうか?

どなたかご存知の方、よろしくご教授ください。

Aベストアンサー

 細かい点ですが
>正規表現を利用して実行してみましたがうまく動作しません。
 と有りますが、実際にでた結果を書いていただけると
回答がしやすいです。
 実際は貴方が書かれているやり方でもとれていると
思うのですが…。

 基本的に私が普段、使うときには
if ($test =~ /\"(.*?)\"/) {
$test= $1;
}
を使用しております。

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

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

Aベストアンサー

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

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 $_; ##出力してみる。
}
}

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


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

人気Q&Aランキング