こんばんはエンジニアの眠れない夜です。
ショッピングサイトのスクレイピングなどをするときにはテキストから商品価格を取得しますよね?
そういう時に「価格」と一言で言っても実に色んなパターンがありうまく「価格」を取得できないという問題があります。
特に海外のショッピングサイトを扱うときには通貨の記号が違ったり、日本円表記には存在しない小数点もあります。
また、取ってきた価格「String」型を計算ができるように他の型にparse()しようとすると余計な文字が入っていてParserErrorが出たり…
そういった問題を解決できるように正規表現を使った価格の前処理関数を作りました。
個人的には結構万能だと思うので皆さん使ってください(^^)/
【使い方】正規表現で価格を取得する
ソースコードの画面の右下にあるview rowを開いて「⌘+S」でソースコードをダウンロードできます。「ファイル→ページとして保存」でも大丈夫です。
ダウンロードしたクラスファイルをJavaのプロジェクトの中に入れるだけです。
※ Regexクラスを作成してコピペでもいいですし、関数自体がstaticなので関数だけをコピペしても大丈夫です。MatcherとPatternのインポートはお忘れなく…
戻り値はStringなのでIntやFloat、Doubleにしてその後は煮るなり焼くなりしてくださいm(_ _)m
対応している価格の抽出パターン
今回、紹介した関数で抽出できる価格のパターンを紹介します。
念の為、assertEquals()の説明をしておくと assertEquals(“引数1”,”引数2”) 引数1,2が同じ値なら何も返さず、異なる値ならエラーが返ってくるという感じです。
toPrice()関数は価格が取れないところは not found price を返すようになっているので取得できないパターンの入力のところには not found price を入れています。
引数1にはテストしたい文字列
引数2にはその期待される戻り値
が入っていると思ってもらえれば大丈夫です。
ザッと見てもらって気づいた思うのですが、価格が一桁の場合は取得できません…
assertEquals(Regex.toPrice("1円"),"not found price");
おい!どこが万能やねん!っと突っ込まれそうですが‥(-_-;)
日本円で一桁の商品がネットショップで売られることはめったにないので、新品を扱う市場なら問題ないと思います。
ヤフオクとかジモティーは例外です。正確さには欠けますが、価格が取れなかったときの not found price を1とか0で返すというのも一つの方法かなとは思います。
海外のショッピングサイトは少数点があるので一桁というのは多分無いと思うので大丈夫だと思います。
assertEquals(Regex.toPrice("1USD"),"not found price");
assertEquals(Regex.toPrice("1.00USD"),"1.00");
その他、対応しているのは価格の前後に通過の記号や表記があったりなかったりというのは全部無視してちゃんと動きます。
assertEquals(Regex.toPrice("100円"),"100");
assertEquals(Regex.toPrice("¥100"),"100");
assertEquals(Regex.toPrice("¥100円"),"100");
これは結構ありがたい。
あと稀にあるのが商品価格の後ろに在庫状況なんかがひっついてきたりするパターン。これも大丈夫です。
assertEquals(Regex.toPrice("¥447.43最後の1点"),"447.43");
assertEquals(Regex.toPrice("¥4,447.43残り10点"),"4447.43");
こんな表記はないと思いますが、これも大丈夫です。
assertEquals(Regex.toPrice("4US¥4,447最後の1点"),"4447");
assertEquals(Regex.toPrice("¥,447.43最後の1点"),"447.43");
対応できなかったのが一番最後の「価格の前に二桁以上のサイズなどの数字があるパターン」一桁だけなら無視できるのですが、二桁あるとその部分を価格として取ってきてしまいます…
なのでRegex.toPrice()に入れる前に調整してあげてください。
最後に一言
「もっといい方法があるんじゃない?」とか
「他にもこんなパターンを正規表現でサクッと解決できる関数があったらいいな…」
みたいなコメント大歓迎です。
個人的には正規表現のパターンを一通り網羅すれば同じことをみんなが考えなくて良くなるのでどんどん色んなパターンを公開して行こうよ!というスタンスです。
正規表現に限らず関数レベルでコピペで使い回せるものはどんどん公開していければいいなと思ってます。
バグも発見されてコードの安定性も増しますしね。
最後にツイッターのフォローもお忘れなく(^^)v
コメントを残す