PHPの質問です。 あるcsvのデータ内で、ダブルクォートで囲まれた金額の値に含まれる、カンマを除きたいと考えております。具体的には"23,798,456"といった値です。除いた後の値は23798456となります。この値の桁数は一定ではないため、カンマの数も変動することが前提となります。


PHPからload data infileでcsvのインポート処理を行う際、上記のカンマの部分が余計なため取り込み時にカンマの前後で値が分割されてしまいます。

これを避けるために、一度インポートの前処理として、preg_replace関数を利用し、置換処理をかけたいと思ってますが、上記の用途を満たす正規表現はどのように書けばよいでしょうか。

回答の条件
  • 1人5回まで
  • 13歳以上
  • 登録:2014/03/17 16:33:24
  • 終了:2014/03/24 16:35:07

回答(2件)

id:a-kuma3 No.1

a-kuma3回答回数4366ベストアンサー獲得回数18022014/03/17 17:38:16

ポイント250pt

preg_replace_callback() を使うと、こんな感じでできます。

<?php

$s = '"23,798,456","567","1,234","9,876,543,210,123"';

$a = preg_replace_callback('/"(\d|,)+"/', 
        function($m) {
            return preg_replace('/,/', '', $m[0]);
        },
        $s);

echo $s . "\n";         
echo $a . "\n";

?>

出力。

"23,798,456","567","1,234","9,876,543,210,123"
"23798456","567","1234","9876543210123"

ideone.com で動作を確認したのが、こちらです。
http://ideone.com/p8bgYr

id:mithmarc

早速のご回答ありがとうございます!目的通りに置換することができました!頂いたスクリプトが理解できるよう、もっと勉強したいと思います。ありがとうございました!!

2014/03/17 18:28:54
id:a-kuma3

ちょっとだけ、解説。


preg_replace_callback 関数は、正規表現で文字列を引き当てた後に、その文字列を指定して、別の処理を呼び出せます。
http://www.php.net/manual/ja/function.preg-replace-callback.php

preg_replace_callback の第一引数に指定した、この正規表現。

/"(\d|,)+"/

ダブルクォートでくくられた、数字とカンマからできている文字列にマッチします。

preg_replace_callback の第二引数は、処理をする無名関数です。
http://php.net/manual/ja/functions.anonymous.php

その無名関数が呼び出されたときの引数には、preg_replace_callback の第一引数で指定した正規表現にマッチした文字列が配列で渡されます。
m[0] は、正規表現全体。つまり、ダブルクォートから始まり、数字とカンマでできた文字列が続き、ダブルクォートで終わる文字列が入ってます。
m[1] 以降は、カッコでグルーピングした文字列が入ります。
今回は使っていませんが、ダブルクォートの内側の数字とカンマでできた文字列が m[1] に入ってます。

第二引数の関数が返した文字列で、正規表現がマッチした文字列が置き換えられます。

最初に第二引数の無名関数に処理が渡ってくるときは、"23,798,456" が m[0] に入ってきます。
無名関数の中で呼んでいる preg_replace で m[0] に含まれるカンマを削除した "23798456" が無名関数も戻り値として返します。
preg_replace_callback は、"23,798,456" を "23798456" で置き換えます。

無名関数は、正規表現にマッチする文字列で、何度も呼ばれます。
二回目は "567"、三回目は "1,234" というふうに。
その度に、無名関数はカンマを取り除いた文字列を返し、preg_replace_callback は、その文字列で置き換えます。

2014/03/17 19:02:28
id:watercooler No.2

井戸端さん回答回数289ベストアンサー獲得回数512014/03/24 07:46:57

ポイント250pt
<?php
$string = '"23,798,456","567","1,234","9,876,543,210,123"';
$pattern = '/"(\d*),*(\d*),*(\d*),*(\d*),*(\d*),*(\d*),*(\d*),*(\d*),*(\d*)"/';
$replacement = '"$1$2$3$4$5$6$7$8$9"';
echo preg_replace($pattern, $replacement, $string);
?>

http://www.php.net/manual/ja/function.preg-replace.php

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません