2017-01-16 92 views
1

在這裏我有下面的代碼。這個想法是,如"R#GUPW*UIOPW#WERTY*RT#LLOPPPPER*CVW"短語返回一個模式像返回相同的字符串中找到的子串

"#GUPW*"
"#WERTY*"
"#LLOPPPPER*"

是從與#開頭,以*結尾那句返回所有的子字符串。所以在這個短語中有3個。

import java.io.*; 

public class Pattern { 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) { 
     // TODO code application logic here 

     String phrase = "R#GUPW*UIOPW#WERTY*RT#LLOPPPPER*CVW"; 
     String found =""; 

     for (int y = 0; y<phrase.length(); y++) 
     { 
     found = found + phrase.substring(phrase.indexOf("#"), phrase.indexOf("*")); 
     } 
     System.out.println(found); 
    } 

} 

,但我的代碼返回 "#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW#GUPW"

我怎麼能返回這些子與#開始,從我的短語*結束。

"#GUPW*"
"#WERTY*"
"#LLOPPPPER*"

+0

'indexOf'時沒有更多的參數調用總是從字符串的開頭searchs。所以它總是會找到「#GUPW」 – Clayn

+0

但這並不明確。您正在遍歷每個字符,但每次都從頭開始使用indexOf方法。如果你這樣迭代,檢查當前字符,如果它是'#'或不。或者只是搜索每個'#'並做你自己的事情。 PS:你的例子不正確,因爲你缺少'*',或者我不明白 – AxelH

+0

問自己,爲什麼你在循環中有y變量?你沒有在任何地方使用它?你希望從程序中獲得獨特的phrase.length()打印輸出嗎?進一步的提示: - 使用while循環,將索引存儲到變量中,以便您可以在更多的子字符串調用中使用它們,並閱讀有關2參數indexOf方法的文檔。 –

回答

2

的解決方案將是,以限定Pattern,然後在Matcher使用它。

List<String> allMatches = new ArrayList<String>(); 
Pattern p = Pattern.compile("#[^*]+\\*"); 
Matcher m = p.matcher(yourString); 
while (m.find()) { 
    allMatches.add(m.group()); 
} 

然後,所有的匹配將出現在List

演示:

String s = "R#GUPW*UIOPW#WERTY*RT#LLOPPPPER*CVW"; 
List<String> allMatches = new ArrayList<String>(); 
Pattern p = Pattern.compile("#[^*]+\\*"); 
Matcher m = p.matcher(s); 
while (m.find()) { 
    allMatches.add(m.group()); 
} 

for (String str : allMatches) { 
    System.out.println(str); 
} 
>>#GUPW* 
>>#WERTY* 
>>#LLOPPPPER* 
+1

I正在等待一個'Pattern'來詢問'#foo * bar * boo'時會附加什麼。有疑問的是,我使用了更多的_manual_解決方案 – AxelH

+0

@AxelH的好處。上面的解決方案會拍照。我相信這是OP想要的。 – xenteros

+0

由於沒有提出這個問題,我沒有把它作爲一個要求。我不確定這會輸出什麼。感謝你的回答! – AxelH

0

已經有一個內部的Apache共享庫,會替你在字符串utils的方法。該方法是StringUtils。 substringsBetween

公共靜態字符串[] substringsBetween(字符串str, 字符串打開, 字符串靠近)搜索由開始和結束標籤界定的子串,返回所有匹配 子陣列中的一個字符串。

null輸入字符串返回null。 null null/close返回null(不匹配 )。空(「」)open/close返回null(不匹配)。

StringUtils.substringsBetween("[a][b][c]", "[", "]") = ["a","b","c"] 
StringUtils.substringsBetween(null, *, *)   = null 
StringUtils.substringsBetween(*, null, *)   = null 
StringUtils.substringsBetween(*, *, null)   = null 
StringUtils.substringsBetween("", "[", "]")   = [] 

參數:

  • STR - 包含的子串,空返回NULL,空返回空
  • 開放字符串 - 字符串識別子串的開始,空返回null關閉 - 標識
  • 的字符串結束 - 子字符串,空返回null返回:字符串子串的數組,如果不匹配,則返回null

此方法不包括在輸出中分隔,所以如果你真的需要它,我想你需要修復與幾行代碼的行爲。

+0

這是使用Apache API。你應該指定它;)不是每個人都使用它(我從來沒有這樣的需求) – AxelH

+0

@AxelH ApacheCommons以及番石榴通常在創建POM時添加到項目中:) – xenteros

+0

我可以同意,永遠不會增加需求我不能判斷;)但這需要在他的回答中。是的,這是鏈接,但這不是新手必須清楚。 (PS,而不是downvoter,我發現這個解決方案很有用,但不完整) – AxelH

0

嘗試循環內的代碼更改爲

int stIndex = phrase.indexOf("#"); 
int endIndex = phrase.indexOf("*"); 
found = found + "\n" + phrase.substring(stIndex, endIndex); 
phrase = phrase.substring(endIndex + 1); 

我所做的是找到後的首場比賽,我除去輸入匹配的字符串。

1

我會簡單地搜索每個*,然後從這個位置找到以前的#(如果有的話)。這應該是這樣的:

String input = "R#test*foo#bar#far#bor*for#"; 

int index = -1, begin; 
while((index = input.indexOf("*", index+1)) > -1){ 
    if((begin = input.lastIndexOf("#", index)) > -1){ //If there is a character 
      // Substract it from the current String 
      System.out.println(input.substring(begin, index + 1)); 
     } 
} 

基本上,尋找下一個*index + 1開始(+ 1,以防止無限循環)與

input.indexOf("*", index+1)) 

從那裏,只需使用String.lastIndexOf從這個搜索放置之前的#。如果子字符串中有兩個*,則此解決方案將同時打印這兩個文件。

這個輸出:

#test 
#bor 
+0

你的輸出是錯誤的......並根據你對多顆星的懷疑。看,OP有三顆星,期望3個輸出,而不是6. – xenteros

+0

@xenteros我的輸出確實缺少'*'。但是,這個輸出與OP示例完全相同的字符串....所以是的,這可能是錯誤的'#foo * bar * far'應該只輸出一個字符串,但這很容易修復(如果需要) – AxelH

-2
String phrase = "R#GUPW*UIOPW#WERTY*RT#LLOPPPPER*CVW"; 
    String[] ph = phrase.substring(phrase.indexOf("#"), phrase.lastIndexOf("*")+1) //get everything between the first "#" and last "*"       
         .replaceAll("\\*.*?#", "*#") // remove all chars between * and # 
         .split("(?<=\\*)"); //split at * and keep the delimiter 
    System.out.println(Arrays.toString(ph)); 
相關問題