2012-06-07 30 views
5

Tôi có chuỗi khớp với cụm từ thông dụng này: ^.+:[0-9]+(\.[0-9]+)*/[0-9]+$ có thể dễ dàng được hiển thị là (Text):(Double)/(Int). Tôi cần phải chia chuỗi này thành ba phần. Thông thường điều này sẽ dễ dàng, ngoại trừ việc (Text) có thể chứa dấu hai chấm, vì vậy tôi không thể phân chia trên bất kỳ dấu hai chấm nào - nhưng thay vào đó là dấu hai chấm cuối cùng.Tùy chọn sử dụng String.split(), chia chuỗi tại lần xuất hiện cuối cùng của dấu phân tách

.* là tham lam nên nó đã làm một công việc khá gọn gàng để làm điều này, nhưng điều này sẽ không hoạt động như một biểu thức chính quy thành String.split() vì nó sẽ ăn (Text) như một phần của dấu phân tách. Lý tưởng nhất là tôi muốn có một cái gì đó mà sẽ trả về một String [] với ba chuỗi. Tôi là 100% tốt với không sử dụng String.split() cho việc này.

Trả lời

3

Tại sao bạn không chỉ sử dụng cụm từ thông dụng thẳng lên?

Pattern p = Pattern.compile("^(.*):([\\d\\.]+)/(\\d+)$"); 
Matcher m = p.matcher(someString); 
if (m.find()) { 
    m.group(1); // returns the text before the colon 
    m.group(2); // returns the double between the colon and the slash 
    m.group(3); // returns the integer after the slash 
} 

Hoặc tương tự. Mẫu ^(.*):([\d\.]+)/(\d+)$ giả định rằng bạn thực sự có giá trị ở cả ba vị trí và sẽ chỉ cho phép một khoảng thời gian/toàn bộ ở vị trí kép, do đó bạn có thể muốn tinh chỉnh thông số của mình.

+0

OK, bây giờ nói rằng thay vì sử dụng '[\ d \.] +' để phù hợp với đôi, nếu tôi muốn được nghiêm ngặt và yêu cầu '\ d + (\. \ d +) *'. Tôi có thể sử dụng an toàn chỉ các nhóm 0,1,3? Đó là để nói, 'sometext: other: 2/4' và 'sometext: other: 2.0/4' sill nhóm theo cùng một cách? – Huckle

+1

Nó sẽ là nhóm 1, 2 và 4, nhưng bạn không cần phải bận tâm với điều đó.Chỉ cần làm cho nhóm mới một không bắt : '\ d + (?: \. \ d +)?' –

+0

nhóm (0) trả về toàn bộ chuỗi phù hợp. Đây là một trong số ít các trường hợp whe chỉ số lại không bắt đầu bằng 0. @AlanMoore có một gợi ý tốt cho một regex kép nghiêm ngặt. –

5

Tôi không thích regex (chỉ đùa thôi nhưng tôi không giỏi lắm).

String s = "asdf:1.0/1" 
String text = s.substring(0,s.lastIndexOf(":")); 
String doub = s.substring(s.lastIndexOf(":")+1,text.indexOf("/")); 
String inte = s.substring(text.indexOf("/")+1,s.length()); 
+0

chuỗi con của bạn sai. Nó bắt đầu tại chỉ số 0 không phải tại 1 – Subs

+0

@ Sơ đồ trang: Tôi muốn bỏ qua chữ cái đầu tiên '('. – tskuzzy

+0

Ông ấy nói '()' cho mục đích trực quan. Đừng nghĩ rằng những dấu ngoặc đó đến trong – Subs

1

String.split() thường được sử dụng trong các trường hợp đơn giản hơn, nơi dấu phân cách và định dạng nhất quán hơn và khi bạn không biết có bao nhiêu phần tử bạn sẽ chia tách.

Trường hợp sử dụng của bạn yêu cầu biểu thức chính quy cũ thông thường. Bạn biết định dạng của chuỗi và bạn biết mình muốn thu thập ba giá trị. Hãy thử một cái gì đó như sau.

Pattern p = Pattern.compile("(.+):([0-9\\.]+)/([0-9]+)$"); 
Matcher m = p.matcher(myString); 
if (m.find()) { 
    String myText = m.group(1); 
    String myFloat = m.group(2); 
    String myInteger = m.group(3); 
} 
Các vấn đề liên quan