2011-11-25 56 views
43

Tôi đang cố gắng để tìm ra một cách để tách một chuỗi trong java rằng sau một mô hình như vậy:Làm thế nào để tách một chuỗi giữa các chữ cái và chữ số (hoặc giữa các chữ số và chữ cái)?

String a = "123abc345def"; 

Kết quả từ này nên là như sau:

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

Tuy nhiên tôi 'm hoàn toàn bối rối như thế nào tôi có thể đạt được điều này. Xin vui lòng ai đó có thể giúp tôi? Tôi đã cố gắng tìm kiếm trực tuyến cho một vấn đề tương tự, tuy nhiên nó rất khó để cụm từ nó một cách chính xác trong một tìm kiếm.

Xin lưu ý: Số lượng chữ & số có thể thay đổi (ví dụ có thể là một chuỗi như vậy '1234a5bcdef')

+0

Tôi chưa thử bất cứ điều gì - Tôi thậm chí không biết bắt đầu từ đâu với vấn đề vì nó là lần đầu tiên thời gian tôi đã đi qua bất cứ điều gì khá giống như nó. –

+0

Người dùng được yêu cầu thêm thẻ "bài tập về nhà" cho tất cả các câu hỏi liên quan đến bài tập về nhà. – Michael

+0

@Michael đây không phải là câu hỏi 'bài tập về nhà'. Tôi chưa bao giờ gặp vấn đề này trước đây. –

Trả lời

74

Bạn có thể thử để phân chia trên (?<=\D)(?=\d)|(?<=\d)(?=\D), như:

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

Nó khớp vị trí giữa một số và không phải một số (theo thứ tự bất kỳ).

+3

Chỉ cần ghi nhớ rằng giải pháp này sẽ đe dọa các ký tự, không phải chữ số cũng như chữ cái, làm chữ cái để bạn có thể muốn xác minh các phần của mình. – Mario

+0

@Romain, nó có: http://ideone.com/XDsKn – Qtax

+0

@TimPietzcker Tôi không phải là người bỏ phiếu xuống câu hỏi này - Tôi chưa bao giờ thấy điều này được sử dụng trong Java và đã thẳng thắn yêu cầu xác nhận nó hoạt động trong Java . Bây giờ tôi thậm chí còn upvoting đó. – Romain

3

Sử dụng hai mẫu khác nhau: [0-9]*[a-zA-Z]* và chia hai lần cho từng mẫu.

+0

Cảm ơn sự giúp đỡ của bạn về điều này. Tôi không chắc tôi hoàn toàn hiểu ý của bạn. Xin bạn có thể giải thích chi tiết hơn một chút hoặc cung cấp một ví dụ cơ bản để tôi có thể hiểu ý của bạn là gì? –

+0

Về mặt ngữ nghĩa, nó sẽ là '[0-9] +' và '[a-zA-Z] +' ... Mặc dù chúng sẽ làm tương tự. – Romain

+0

trước hết bạn chia chuỗi của bạn trên mẫu chữ số và nhận mảng chuỗi, sau đó bạn tách chuỗi trên mẫu chữ và nhận mảng các số. Nối hai mảng bạn sẽ nhận được những gì bạn muốn – mishadoff

1

Không sử dụng Java cho các độ tuổi, vì vậy chỉ cần một số mã giả, điều đó sẽ giúp bạn bắt đầu (nhanh hơn cho tôi hơn là tìm kiếm mọi thứ :)).

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

Làm thế nào về:

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

Cảm ơn .. Đó là yêu cầu thực sự của tôi .. :) –

8

Bạn có thể thử này:

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

kết quả

The (allMatches) sẽ là:

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

Đây không phải là cú pháp Java hợp lệ. –

+0

Cảm ơn Christoffer, tôi đã chỉnh sửa. –

2

Nếu bạn đang tìm kiếm giải pháp mà không cần sử dụng Java String functi onality (tức là split, match, vv) thì những điều sau đây sẽ giúp:

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'; 
    } 

Giải pháp này sẽ chia số và 'lời', nơi 'lời' là chuỗi không chứa số. Tuy nhiên, nếu bạn muốn chỉ có 'các từ' chứa các chữ cái tiếng Anh thì bạn có thể dễ dàng sửa đổi nó bằng cách thêm các điều kiện khác (như gọi số isNumber) tùy theo yêu cầu của bạn (ví dụ: bạn có thể bỏ qua các từ có chứa các chữ cái không phải tiếng Anh). Cũng lưu ý rằng phương thức splitString trả về ArrayList mà sau này có thể được chuyển đổi thành mảng String.

+0

Tôi thích mã của bạn, một nhận xét: return c> = '0' && c <= '9' là imo tốt hơn. –

+0

@ LaurensOp'tZandt - bắt tốt, chỉnh sửa. – sergeyan

1

Tôi đã thực hiện loại điều này cho mã quan trọng của nhiệm vụ. Giống như mọi phần nhỏ của một giây được tính bởi vì tôi cần xử lý 180k mục trong một khoảng thời gian không đáng kể. Vì vậy, tôi bỏ qua regex và phân chia hoàn toàn và cho phép xử lý nội tuyến của mỗi phần tử (mặc dù thêm chúng vào một ArrayList<String> sẽ là tốt). Nếu bạn muốn làm điều này chính xác nhưng cần nó để có một cái gì đó như 20x nhanh hơn ...

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)); 
} 
Các vấn đề liên quan