web-dev-qa-db-ja.com

Java既知のパターンを使用して文字列から値を解析するためのsscanfと同等のものは何ですか?

だから私はCのバックグラウンドから来て(元々、私はほぼ5年間その言語を使用していませんでした)、Javaの文字列からいくつかの値を解析しようとしています。 Cでは、sscanfを使用します。 In Java人々は「スキャナー、またはStringTokenizerを使用する」と言ってきましたが、目的を達成するためにそれらを使用する方法がわかりません。

入力文字列は「17-MAR-11 15.52.25.000000000」のようになります。 Cでは、次のようなことをします。

sscanf(thestring, "%d-%s-%d %d.%d.%d.%d", day, month, year, hour, min, sec, fracpart);

しかし、Javaでは、次のようなことしかできません。

scanner.nextInt();

これにより、パターンを確認することができず、「MAR」の場合、次のようなことをしなければなりません。

str.substring(3,6);

恐ろしい!確かにもっと良い方法がありますか?

29
Kidburla

問題は、JavaがCまたはC#としてパラメーターを出力しない(または参照渡しする)ことです。

しかし、より良い方法があります(そしてより強固です)。正規表現を使用します。

Pattern p = Pattern.compile("(\\d+)-(\\p{Alpha}+)-(\\d+) (\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)")
Matcher m = p.matcher("17-MAR-11 15.52.25.000000000");
day = m.group(1);
month= m.group(2);
....

もちろん、Cコードはより簡潔ですが、この手法には1つの利点があります。パターンは、 '%s'および '%d'よりも正確な形式を指定します。そのため、\ d {2}を使用して、その日を正確に2桁で構成する必要があることを指定できます。

39
korifey

スキャナーを使用したソリューションは次のとおりです。

Scanner scanner = new Scanner("17-MAR-11 15.52.25.000000000");

Scanner dayScanner = new Scanner(scanner.next());
Scanner timeScanner = new Scanner(scanner.next());

dayScanner.useDelimiter("-");
System.out.println("day=" + dayScanner.nextInt());
System.out.println("month=" + dayScanner.next());
System.out.println("year=" + dayScanner.nextInt());

timeScanner.useDelimiter("\\.");
System.out.println("hour=" + timeScanner.nextInt());
System.out.println("min=" + timeScanner.nextInt());
System.out.println("sec=" + timeScanner.nextInt());
System.out.println("fracpart=" + timeScanner.nextInt());
22
dsboger

これらの例はどれも私にとって本当に満足のいくものではなかったので、独自のJava sscanfユーティリティを作成しました。

https://github.com/driedler/Java-sscanf/tree/master/src/util/sscanf

16進文字列の解析の例を次に示します。

String buffer = "my hex string: DEADBEEF\n"
Object output[] = Sscanf.scan(buffer, "my hex string: %X\n", 1);

System.out.println("parse count: " + output.length);
System.out.println("hex str1: " + (Long)output[0]);

// Output:
// parse count: 1
// hex str1: 3735928559
11
user1495323

「17-MAR-11 15.52.25.000000000」の場合:

SimpleDateFormat format = new SimpleDateFormat("dd-MMM-yy HH.mm.ss.SSS");

try 
{
    Date parsed = format.parse(dateString);
    System.out.println(parsed.toString());
}
catch (ParseException pe)
{
    System.out.println("ERROR: Cannot parse \"" + dateString + "\"");
}
3

これは正規表現を使用して得られるエレガントなソリューションとはほど遠いですが、機能するはずです。

public static void stringStuffThing(){
String x = "17-MAR-11 15.52.25.000000000";
String y[] = x.split(" ");

for(String s : y){
    System.out.println(s);
}
String date[] = y[0].split("-");
String values[] = y[1].split("\\.");

for(String s : date){
    System.out.println(s);
}
for(String s : values){
    System.out.println(s);
}
2
Zavior

正規表現の概念に精通していますか? Javaは、Patternクラスを使用して正規表現を使用する機能を提供します。これを確認してください。 http://docs.Oracle.com/javase/8/docs/api /Java/util/regex/Pattern.html

次のように文字列をテストできます。

Matcher matcher = Pattern.match(yourString);
matcher.find();

次に、Matcherが提供するメソッドを使用して、見つかった文字列またはそうでない文字列を操作します。

0
Nikola Yovchev