Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

正規表現の変換にてエラー

お疲れ様です。
文字列中の$today(5)という文字列を、2009年4月7日(今日(2009/4/2)の5日後)という文字列に
変換したく、以下のようなプログラムを書きました。


import java.util.*;
import java.text.*;

public class test6{
    static SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日");

    public static void main(String[] args){
        String in = "$today(5)";
        String s;
        String out = in.replaceAll("\\$today\\((\\d+)\\)",today("$1"));
        System.out.println(out);

    }
    private static String today2(String i){
        return i;
    }
    private static String today(String i){
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.DATE, new Integer(i));
        return format.format(c.getTime());
    }
}
-------------------------------
today2()だと、5と出力されるため、iには5が入っていると思うのですが、
today()だと、
NumberFormatException: For InputString: "$1"
とエラーになってしまいます。
なぜiには5が入っているはずなのに、InputStringが"$1"となってしまうのか理解できません。

正規表現ライブラリの使い方の問題だと思うのですが、原因について分かるかた、ご教授いただけませんか?
よろしくお願いいたします。

7

回答

6754

閲覧

7件の回答

評価

0

書込みをした直後なんですが、原因が分かりました・・・
結局、"$1"を5に置き換えるのは、replaceAll自身なんですね。iにはやはり$1が入ってました。

perlのように、後から$1を使って計算したりする事は、結局javaではできないのでしょうか・・・

評価

0

today("$1")が実行されてからreplaceAll()が実行されるからだよ。
やるならtoday(pattern.matcher(in).group())のように、数字を取り出してから、メソッドを呼ばなきゃ。

で、

>c.setTime(new Date());
これ余計。

>new Integer(i)
Integerのインスタンスを作ってそこからauto-unboxでintの5になってる。
Integer.parseInt(i)でいいだろ。

評価

0

レスありがとうございます。
ご指摘頂いたとおり直してみました。

import java.util.*;
import java.text.*;
import java.util.regex.*;

public class test7{
    static SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日");

    public static void main(String[] args){
        String in = "$today(5)";

        Pattern p = Pattern.compile("\\$today\\((\\d+)\\)");
        Matcher m = p.matcher(in);
        System.out.println(m.group());

        System.out.println(m.replaceAll(today(m.group())));
    }
    private static String today(String i){
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DATE, Integer.parseInt(i));
        return format.format(c.getTime());
    }
}

ですが、m.group()で、no match foundだそうです。
もう少しでできそうですが・・・難しいですね。

評価

0

良く考えたら、1回しか実行しないならわざわざPattern使って抽出することないなー。

String out = today(in.replaceAll("\\$today\\((\\d+)\\)","$1"));

順番変えるだけでOKだ。

一応、何度も同じ処理する必要があるならPatternを使うほうがいい。
で、なんでだめかは、

http://www.javaroad.jp/java_character7.htm

ここを見る。ちゃんとサンプルを確認のこと。

評価

0

なんとかできましたのでご報告します。
複数の$today(i)も変換できるようになりました。
助言ありがとうございました。m(_ _)m

import java.util.*;
import java.text.*;
import java.util.regex.*;

public class test7{
    static SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日");

    public static void main(String[] args){
        String in = "***$today(5) *** $today(7) *** $today(5)";
        String out = in;

        Pattern p = Pattern.compile("\\$today\\((\\d+)\\)");
        Matcher m = p.matcher(in);
        while(m.find()){
            String from = m.group(0);
            String to   = today(m.group(1));
            out = out.replace(from,to);
        }
        System.out.println(out);
    }
    private static String today(String i){
        Calendar c = Calendar.getInstance();
        c.add(Calendar.DATE, Integer.parseInt(i));
        return format.format(c.getTime());
    }

評価

0

んー…。out.replace()の時点で、正規表現インスタンスが別にできてるんだが…。
まあいいや。

評価

0

あ、ちがうか。replace()は固定文字列か…じゃあいいか。

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。