2014-05-16 64 views
1

即使在在線閱讀大量教程之後,我仍然很難在Java中使用正則表達式。我試圖提取部分的字符串,以便稍後在我的應用程序中使用。使用正則表達式提取特定模式

這裏有可能的字符串的示例接收的:

53248 <CERCLE> 321 211 55 </CERCLE> 
57346 <RECTANGLE> 272 99 289 186 </RECTANGLE> 

第一個數字是要被提取作爲序列號。 <>之間的詞也將被提取。然後,中間的數字序列也是如此。

這裏是我的模式:

"(\\d+)\\s*<(\\w+)>\\s*((\\d+\\s*)+)\\s*</\\w*>.*" 

這是迄今爲止對我的方法的代碼:

public decompose(String s) throws IllegalArgumentException { 

    Pattern pattern = Pattern.compile(PATTERN); 
    Matcher matcher = pattern.matcher(s); 

    noSeq = Integer.parseInt(matcher.group(1)); 
    type = typesFormes.valueOf(matcher.group(2)); 
    strCoords = matcher.group(3).split(" "); 

} 

問題是,當我運行的代碼,我所有的匹配組是在-1出於某種原因(未發現我猜)。我一直對此感到震驚,歡迎提供任何建議:)謝謝。

+3

我想你需要首先運行'matcher.find()'。我剛纔有一個類似於這個問題:http://stackoverflow.com/questions/23657575/java-regex-to-parse-any-number-of-markdown-style-links – 2rs2ts

+1

更具體地說,要麼' matcher.find()','matcher.matches()','matcher.lookingAt()'。請參閱[Matcher](http://docs.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html)javadoc。 – ajb

回答

1

正如@ 2rs2ts指出的,問題在於缺少matcher.find()調用。

我將進一步改善這樣的:

final String PATTERN = "(\\d+)\\s*<(\\w+)>\\s*([\\d\\s]+)\\s*</\\2>.*"; 
String s = "53248 <CERCLE> 321 211 55 </CERCLE>"; 
Pattern pattern = Pattern.compile(PATTERN); 
Matcher matcher = pattern.matcher(s); 
if (matcher.find()) { 
    System.out.println(matcher.group(1)); 
    System.out.println(matcher.group(2)); 
    System.out.println(matcher.group(3).trim()); 
} 

一些改進:

  • ,該圖形中,您可以簡化((\\d+\\s*)+)([\\d\\s]+)。爲了您的目的,它是相同的。
  • 在該模式中,您可能希望匹配<CERCLE>與關閉</CERCLE>而不是</OTHER>。您可以使用\\2這是對第二個捕獲組的反向引用。
  • 您可以根據matcher.find()的結果判斷是否有任何匹配項。
  • 在分割中間的數字列表之前,可能會想要使用.trim()修剪末尾可能出現的空白。
+0

添加條件確實是一個好主意。不過,我相信它與方法的拋出毫無用處(錯誤將在其他地方處理) 至於數字,我用不同的方法做到這一點,同時修剪。 對(INT I = 0;我 JulioQc

+0

嗨@JulioQc,那點更多是爲了說明。如果在你的設計中通過允許異常冒泡來處理這些情況更合適,那麼通過一切手段,這樣做,這是你的呼叫。 – janos

1

只需使用String#split()

String str="53248 <CERCLE> 321 211 55 </CERCLE>"; 
    String[] array=str.split("(\\s<|>\\s)"); 
    // simple regex (space <OR> space) 

注嘗試:用\\s+嘗試,如果有一個或多個空格。

在這種情況下,使用前三個數組的值將爲53248, CERCLE, 321 211 55


完整代碼:

String str = "53248 <CERCLE> 321 211 55 </CERCLE>"; 
String[] array = str.split("(\\s<|>\\s)"); 

int noSeq = Integer.valueOf(array[0]); 
String type = array[1]; 
String strCoords = array[2]; 

System.out.println(noSeq+", "+type+", "+strCoords); 

輸出:

53248, CERCLE, 321 211 55 
+0

看起來有效,但我這樣做是爲了上大學,並且要求是使用正則表達式來分割字符串。 – JulioQc

+0

您對'split()'方法中使用的'\\ s <|> \\ s'有什麼看法?是不是一個正則表達式? – Braj

1

你只需要告訴匹配,開始對匹配輸入字符串的模式。這對我的作品上ideone

String s = "53248 <CERCLE> 321 211 55 </CERCLE>"; 
String PATTERN = "(\\d+)\\s*<(\\w+)>\\s*((\\d+\\s*)+)\\s*</\\w*>.*"; 
Pattern pattern = Pattern.compile(PATTERN); 
Matcher matcher = pattern.matcher(s); 
matcher.find();       // aye, there's the rub 
System.out.println(matcher.group(1)); 
System.out.println(matcher.group(2)); 
System.out.println(matcher.group(3)); 

產量爲:

53248 
CERCLE 
321 211 55 

find()方法,成功的時候,會讓匹配產量您想要的信息。從javadocs:

如果匹配成功,則可以通過start,end和group方法獲取更多信息。

group()說同樣的東西指示,重點煤礦:

返回在以前匹配操作期間由給定組捕獲輸入序列。

+0

哇,太棒了!在將來使用匹配器時,我會記下這個.find()=) – JulioQc