2015-12-25 12 views
7

を、私は、次のAWSコストインスタンステーブルを解析しています:は、正規表現を使用してテーブルを解析 - Javaの

m1.small 1 1 1.7  1 x 160 $0.044 per Hour 
m1.medium 1 2 3.75 1 x 410 $0.087 per Hour 
m1.large 2 4 7.5  2 x 420 $0.175 per Hour 
m1.xlarge 4 8 15  4 x 420 $0.35 per Hour 

これらのコストを持つファイルがあります:

input = new Scanner(file); 
String[] values; 
while (input.hasNextLine()) { 
    String line = input.nextLine(); 
    values = line.split("\\s+"); // <-- not what I want... 
    for (String v : values) 
     System.out.println(v); 
} 

しかしそれは私に与える:

は、
m1.small 
1 
1 
1.7 
1 
x 
160 
$0.044 
per 
Hour 

これは私が望むものではありません...修正された解析済みのvalues(正規表現付き)はl IKEこの:

['m1.small', '1', '1', '1.7', '1 x 160', '$0.044', 'per Hour'] 

何正しい結果を得るためには、右regexでしょうか?テーブルは常に同じパターンを持つと仮定できます。

+4

実際のデータはタブで区切られていますか?列が1つのスペースで区切られる場合がありますか? – Pietu1998

+0

@ Pietu1998大抵...しかし必ずしもそうではありません...正規表現はより頑丈なものを生成するでしょう...なぜ私は '\\ t +'で解析するように動かなかったのですか?これらのファイルは膨大なので、欠落しているタブを修正するためにそれらのファイルを無意識に検索することがあります。 – cybertextron

+0

'\\ s {2、}'を使用できますか? –

答えて

4

1つ以上のスペースで分割します。そして、スペースは以下の文脈の中に現れなければならない。

DIGIT - SPACES - NOT "X"

または

NOT "X" - SPACES - あなたは正規表現を使用する場合DIGIT

values = line.split("(?<=\\d)\\s+(?=[^x])|(?<=[^x])\\s+(?=\\d)"))); 
+0

ブーム!ありがとうございました – cybertextron

+0

@ただ一つのこと...いくつかの行は 'EBS Only $ 0.024'を持っていますので、これも一致するはずです...この場合、' ['EBS Only'、 '$ 0.024'] '..私はそれを追加しようとしたが、うまくいかなかった... – cybertextron

5

このバイオリンを試してみてください https://regex101.com/r/sP6zW5/1

([^\s]+)\s+(\d+)\s+(\d+)\s+([\d\.]+)\s+(\d+ x \d+)\s+(\$\d+\.\d+)\s+(per \w+)

は、テキストやグループがあなたのリストで一致します。

私はあなたのケースで使用分割はあまりにも複雑だと思います。テキストは常に同じです。ちょうど文字列書式の逆の手順のように。

+0

amow、もうひとつ... 'Java'は'無効なエスケープシーケンス 'について嫌になっています...どうすれば修正できますか? – cybertextron

+1

2回ごとに\\ – amow

4

、あなたがこれを行うと思います:

 String s = "m1.small 1 1 1.7  1 x 160 $0.044 per Hour"; 
     String spaces = "\\s+"; 
     String type = "(.*?)"; 
     String intNumber = "(\\d+)"; 
     String doubleNumber = "([0-9.]+)"; 
     String dollarNumber = "([$0-9.]+)"; 
     String aXb = "(\\d+ x \\d+)"; 
     String rest = "(.*)"; 

     Pattern pattern = Pattern.compile(type + spaces + intNumber + spaces + intNumber + spaces + doubleNumber 
       + spaces + aXb + spaces + dollarNumber + spaces + rest); 
     Matcher matcher = pattern.matcher(s); 
     while (matcher.find()) { 
      String[] fields = new String[] { matcher.group(1), matcher.group(2), matcher.group(3), matcher.group(4), 
        matcher.group(5), matcher.group(6), matcher.group(7) }; 
      System.out.println(Arrays.toString(fields)); 
     } 

正規表現をどのように分解して読めるようになっているかに注目してください。 (1つの長いStringとして、読み込み/保守するのは難しいです。)しかし、もう1つの方法があります。どのフィールドが分​​割されているか分かっているので、この単純な分割を行い、組み合わせた値で新しい配列を作成することができます:

 String[] allFields = s.split("\\s+"); 
     String[] result = new String[] { 
      allFields[0], 
      allFields[1], 
      allFields[2], 
      allFields[3], 
      allFields[4] + " " + allFields[5] + " " + allFields[6],   
      allFields[7], 
      allFields[8] + " " + allFields[9] }; 
     System.out.println(Arrays.toString(result)); 
関連する問題