2011-11-25 146 views
43

我試圖制定出如下像這樣的模式在Java分裂的字符串的方法:如何在字母和數字之間(或數字和字母之間)分割字符串?

String a = "123abc345def"; 

的從這個結果應該是以下幾點:

x[0] = "123"; 
x[1] = "abc"; 
x[2] = "345"; 
x[3] = "def"; 

不過我我完全無法理解我如何實現這一目標。請有人幫助我嗎?我嘗試過在網上搜索類似的問題,但是在搜索中正確地使用它是非常困難的。

請注意: &數字可能會有所不同的字母數字(例如有可能是像這樣「1234a5bcdef」字符串)

+0

我還沒有嘗試任何事情 - 我甚至不知道在哪裏的問題開始,因爲它是第一個我曾經遇到過類似的東西。 –

+0

要求用戶爲所有關於作業問題的問題添加「作業」標籤。 – Michael

+0

@邁克爾這不是一個'家庭作業'的問題。我以前從未遇到過這樣的問題。 –

回答

74

你可以嘗試拆就(?<=\D)(?=\d)|(?<=\d)(?=\D),如:

str.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)"); 

它匹配數字和非數字(以任意順序)之間的位置。

+3

請記住,該解決方案會將字符(既不是數字也不是字母)威脅爲字母,因此您可能需要驗證您的零件。 – Mario

+0

@Romain,它的確如此:http://ideone.com/XDsKn – Qtax

+0

@TimPietzcker我不是一個投票的這個問題 - 我從來沒有見過這個在Java中使用,並坦率地要求確認它在Java中的作用。現在我甚至都在鼓吹這個。 – Romain

3

使用兩種不同的模式:[0-9]*[a-zA-Z]*,並由它們中的每一個分開兩次。

+0

感謝您的幫助。我不確定我完全理解你的意思。請你能詳細解釋一下,或者提供一個基本的例子,這樣我就能明白你的意思了嗎? –

+0

從語義上講,它會是'[0-9] +'和'[a-zA-Z] +'......儘管他們也會這樣做。 – Romain

+0

首先,將字符串分割爲數字模式並獲取字符串數組,然後在字符模式中分割字符串並獲取數組數組。連接兩個數組,你將得到你想要的結果 – mishadoff

1

沒有使用Java的年齡,所以只是一些僞代碼,這應該幫助你開始(比查找所有東西更快:))。

string a = "123abc345def"; 
string[] result; 
while(a.Length > 0) 
{ 
     string part; 
     if((part = a.Match(/\d+/)).Length) // match digits 
      ; 
     else if((part = a.Match(/\a+/)).Length) // match letters 
      ; 
     else 
      break; // something invalid - neither digit nor letter 
     result.append(part); 
     a = a.SubStr(part.Length - 1); // remove the part we've found 
} 
9

如何:

private List<String> Parse(String str) { 
    List<String> output = new ArrayList<String>(); 
    Matcher match = Pattern.compile("[0-9]+|[a-z]+|[A-Z]+").matcher(str); 
    while (match.find()) { 
     output.add(match.group()); 
    } 
    return output; 
} 
+0

謝謝..其實我的要求.. :) –

8

你可以試試這個:

Pattern p = Pattern.compile("[a-z]+|\\d+"); 
Matcher m = p.matcher("123abc345def"); 
ArrayList<String> allMatches = new ArrayList<>(); 
while (m.find()) { 
    allMatches.add(m.group()); 
} 

結果(allMatches)將是:

["123", "abc", "345", "def"] 
+0

這是無效的Java語法。 –

+0

感謝Christoffer,我編輯過。 –

2

如果您正在尋找解決方案而不使用Java String函數性(即splitmatch等),那麼以下應該有所幫助:

List<String> splitString(String string) { 
     List<String> list = new ArrayList<String>(); 
     String token = ""; 
     char curr; 
     for (int e = 0; e < string.length() + 1; e++) { 
      if (e == 0) 
       curr = string.charAt(0); 
      else { 
       curr = string.charAt(--e); 
      } 

      if (isNumber(curr)) { 
       while (e < string.length() && isNumber(string.charAt(e))) { 
        token += string.charAt(e++); 
       } 
       list.add(token); 
       token = ""; 
      } else { 
       while (e < string.length() && !isNumber(string.charAt(e))) { 
        token += string.charAt(e++); 
       } 
       list.add(token); 
       token = ""; 
      } 

     } 

     return list; 
    } 

boolean isNumber(char c) { 
     return c >= '0' && c <= '9'; 
    } 

該解決方案將分爲數字和「字」,其中「字」是不包含數字的字符串。但是,如果您只想包含英文字母的「單詞」,則可以根據您的要求(例如,您可能希望跳過包含非英文字母的單詞)添加更多條件(如isNumber方法調用)來輕鬆修改它。另請注意,splitString方法返回ArrayList,以後可以將其轉換爲String陣列。

+0

我喜歡你的代碼,一個評論:return c> ='0'&& c <='9'更好。 –

+0

@ LaurensOp'tZandt - 編輯好。 – sergeyan

1

我在爲關鍵任務代碼做這類事情。就像每一秒鐘的一小部分,因爲我需要在不可察覺的時間內處理18萬個條目。所以我跳過了正則表達式並完全拆分,並允許對每個元素進行內聯處理(儘管將它們添加到ArrayList<String>將會很好)。如果你想要做這個確切的事情,但需要的是像快20倍......

void parseGroups(String text) { 
    int last = 0; 
    int state = 0; 
    for (int i = 0, s = text.length(); i < s; i++) { 
     switch (text.charAt(i)) { 
      case '0': 
      case '1': 
      case '2': 
      case '3': 
      case '4': 
      case '5': 
      case '6': 
      case '7': 
      case '8': 
      case '9': 
       if (state == 2) { 
        processElement(text.substring(last, i)); 
        last = i; 
       } 
       state = 1; 
       break; 
      default: 
       if (state == 1) { 
        processElement(text.substring(last, i)); 
        last = i; 
       } 
       state = 2; 
       break; 
     } 
    } 
    processElement(text.substring(last)); 
} 
相關問題