2015-12-25 2 views
7

मैं निम्नलिखित AWS लागत उदाहरण तालिका को पार्स कर रहा हूँ:regex का उपयोग कर एक मेज पार्स - जावा

:

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 
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 

वहाँ उन लागत के साथ एक फ़ाइल है

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

जो मैं नहीं चाहता ... एक सही पार्स किया गया values (दाएं रेगेक्स के साथ) एल देखेंगे इस आइक:

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

क्या सही regex आदेश सही परिणाम प्राप्त करने के लिए हो सकता है? कोई यह मान सकता है कि तालिका हमेशा एक ही पैटर्न होगी।

+4

क्या वास्तविक डेटा टैब से अलग है? क्या ऐसे कई उदाहरण हो सकते हैं जहां कॉलम केवल एक स्थान से सीमित हो? – Pietu1998

+0

@ Pietu1998 अधिकतर ... लेकिन जरूरी नहीं ... रेगेक्स कुछ और मजबूत पैदा करेगा ... कि मैं '\\ t +' के साथ पार्स क्यों नहीं चला गया। वे फ़ाइलें बहुत बड़ी हैं, इसलिए यह अनुपलब्ध टैब को ठीक करने के लिए उन फ़ाइलों को व्यर्थ खोज सकता है। – cybertextron

+0

क्या आप '\\ s {2,}' का उपयोग कर सकते हैं? –

उत्तर

4

एक और अधिक रिक्त स्थान से विभाजित करें। और रिक्त स्थान नीचे दिए गए संदर्भ में प्रकट होना चाहिए।

अंक - खाली स्थान - नहीं "x"

या

नहीं "x" - खाली स्थान - अंक

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

बूम डबल!बहुत बहुत धन्यवाद – cybertextron

+0

@ बस एक और बात ... कुछ पंक्तियों में 'ईबीएस केवल $ 0.024' है, इसलिए इसे इसके लिए भी मिलना चाहिए ... इस मामले में,' ['केवल ईबीएस', '$ 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

एलो, एक और बात ... 'जावा'' अमान्य भागने अनुक्रम 'के बारे में चिल्ला रहा है ... मैं इसे कैसे ठीक करूँगा? – cybertextron

+1

प्रत्येक '\\' – 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)); 
     } 

ध्यान दें कि मैंने नियमित अभिव्यक्ति को पढ़ने योग्य कैसे टूटा है। (एक लंबे स्ट्रिंग के रूप में, इसे पढ़ना/बनाए रखना मुश्किल है।) हालांकि ऐसा करने का एक और तरीका है। चूंकि आप जानते हैं कि कौन से फ़ील्ड विभाजित किए जा रहे हैं, आप केवल यह सरल विभाजन कर सकते हैं और संयुक्त मानों के साथ एक नई सरणी बना सकते हैं:

 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)); 
संबंधित मुद्दे