2010-09-23 25 views

Trả lời

26
str.split("(?=[:;])") 

Điều này sẽ cung cấp cho bạn mảng mong muốn, chỉ với một mục đầu tiên trống. Và:

str.split("(?=\\b[:;])") 

Điều này sẽ cung cấp cho mảng mà không có mục đầu tiên trống.

  • Mấu chốt ở đây là (?=X) mà là một zero-width lookahead dương (phi chụp xây dựng) (xem regex pattern docs).
  • [:;] có nghĩa là "một trong hai, hoặc:"
  • \b là word-ranh giới - đó là có để không phải xem xét : đầu tiên như delimiter (vì nó là sự khởi đầu của chuỗi)
+0

'(? = X)' là "lookahead dương không có chiều rộng", nhóm không chụp là '(?: X)'. Điều này sẽ không hoạt động chính xác với nhóm không chụp ... –

+0

@Carlos Heuberger bạn có thể giải thích thêm không? Nó thực sự hoạt động theo cách này (thử nghiệm nó), nhưng tôi có thể đã bỏ lỡ một cái gì đó – Bozho

+1

nó hoạt động nhưng trình tự '(? = X)' không được gọi là "nhóm không bắt", hoặc ít nhất không phải là nhóm "không bắt giữ" đơn giản . Nó được gọi là "lookahead tích cực zero-width". "Nhóm không bắt giữ" là '(?: X)'. (xin lỗi vì tiếng Anh xấu của tôi) –

4

Để giữ cho dải phân cách, bạn có thể sử dụng một StringTokenizer:

new StringTokenizer(":alpha;beta:gamma;delta", ":;", true) 

Điều đó sẽ mang lại dải phân cách như thẻ.

Để có chúng như một phần của mã thông báo, bạn có thể sử dụng String#split với lookahead.

+3

"StringTokenizer là một lớp kế thừa" – Bozho

+3

@Bozho Đúng vậy, nhưng tôi nghĩ rằng trường hợp này sử dụng cụ thể của việc giữ delimiters không được đề cập rất độc đáo bởi Chuỗi #split, yêu cầu một số kiến ​​thức regex chi tiết để có được điều đó. –

+0

đúng, nó rõ ràng hơn một chút với StringTokenizer, vì nó có tùy chọn mong muốn làm tham số boolean. 1, điểm về di sản vẫn còn hợp lệ. – Bozho

-1

Giả sử rằng bạn chỉ có một tập hợp các bộ tách riêng trước khi các từ trong chuỗi của bạn (ví dụ:,, v.v.) bạn có thể sử dụng kỹ thuật sau đây. (Xin lỗi cho bất kỳ lỗi cú pháp, nhưng nó được một thời gian kể từ khi tôi sử dụng Java)

String toSplit = ":alpha;beta:gamma;delta " 
toSplit = toSplit.replace(":", "~:") 
toSplit = toSplit.replace(";", "~;") 
//repeat for all you possible seperators 
String[] splitStrings = toSplit.split("~") 
+0

điều này đơn giản hơn. – Joset

+0

1. Không chính xác vì nó trả về phần tử thứ 0 trống. 2. Nó làm tăng cơ hội lỗi do trùng lặp (tức là ":" phải được ghép nối với "~:") 3. Điều gì xảy ra nếu dấu phân cách đặc biệt "~" được sử dụng trong một trong các phần tử? –

+0

@Tony, tôi đã chọn "~" làm ví dụ nhưng bất kỳ dấu phân tách duy nhất nào khác có thể được sử dụng phù hợp với tập dữ liệu có sẵn. Tôi không hoàn toàn thấy làm thế nào nó làm tăng cơ hội lỗi - có lẽ bạn có thể làm rõ điểm đó. Tôi thừa nhận nó không để lại một phần tử rỗng thứ 0 mà là một thất bại của phương pháp này, nhưng tôi muốn trình bày một tùy chọn khác mà không phụ thuộc vào regex – chillysapien

1

Bạn có thể làm điều này bằng cách đơn giản sử dụng các mẫu và lớp khớp trong java regx.

public static String[] mysplit(String text) 
    { 
    List<String> s = new ArrayList<String>(); 
    Matcher m = Pattern.compile("(:|;)\\w+").matcher(text); 
    while(m.find()) { 
    s.add(m.group()); 
    } 
    return s.toArray(new String[s.size()]); 
    } 
+0

Một khi regexp djinni là ra khỏi chai, tôi thích giải pháp của Bozho. –

+0

Yup .. tôi đồng ý ... ở trên chỉ là một cách alt để làm điều đó :) – Favonius

1
/** 
* @param list an empty String list. used for internal purpose. 
* @param str String which has to be processed. 
* @return Splited String Array with delimiters. 
*/ 
public String[] split(ArrayList<String> list, String str){ 
    for(int i = str.length()-1 ; i >=0 ; i--){ 
    if(!Character.isLetterOrDigit((str.charAt(i)))) { 
     list.add(str.substring(i, str.length())); 
     split(list,str.substring(0,i)); 
     break; 
    } 
    } 
    return list.toArray(new String[list.size()]); 
} 
+1

Đây chỉ là một cách khác! cho những người không biết về regex như tôi :) –

0

này nên làm việc với Java 1.5 (Pattern.quote đã được giới thiệu trong Java 1.5).

// Split the string on delimiter, but don't delete the delimiter 
private String[] splitStringOnDelimiter(String text, String delimiter, String safeSequence){ 
    // A temporary delimiter must be added as Java split method deletes the delimiter 

    // for safeSequence use something that doesn't occur in your texts 
    text=text.replaceAll(Pattern.quote(delimiter), safeSequence+delimiter); 
    return text.split(Pattern.quote(safeSequence)); 
} 

Nếu yếu tố đầu tiên là vấn đề:

private String[] splitStringOnDelimiter(String text, String delimiter, String safeSequence){ 
    text=text.replaceAll(Pattern.quote(delimiter), safeSequence+delimiter); 
    String[] tempArray = text.split(Pattern.quote(safeSequence)); 
    String[] returnArray = new String[tempArray.length-1]; 
    System.arraycopy(tempArray, 1, returnArray, 0, returnArray.length); 
    return returnArray; 
} 

Ví dụ:, Ở đây "a" là delimiter:

splitStringOnDelimiter("-asd-asd-g----10-9asdas jadd", "a", "<>") 

Bạn có được điều này:

1.: - 
2.: asd- 
3.: asd-g----10-9 
4.: asd 
5.: as j 
6.: add 

Nếu bạn thực sự muốn điều này:

1.: -a 
2.: sd-a 
3.: sd-g----10-9a 
4.: sda 
5.: s ja 
6.: dd 

Bạn chuyển:

safeSequence+delimiter 

với

delimiter+safeSequence 
Các vấn đề liên quan