2013-06-28 22 views
13

Tôi đã tìm trong Java API và một số thư viện của bên thứ 3 phổ biến nhưng tôi không thể tìm thấy một phương thức phù hợp sẽ làm những gì String.replaceAll làm, ngoại trừ StringBuilder.replaceAll cho StringBuilder có hỗ trợ regex không?

Tôi biết rằng với một công việc nhỏ, nó có thể được thực hiện cho StringBuffer, nhưng tôi không muốn đi xuống con đường này vì StringBuffer chậm hơn.

Có ai biết về bất kỳ utilies của bên thứ ba nào không hoặc nếu có một đoạn mã nhanh để triển khai chức năng này?

+0

Đó có phải là hiệu suất quan trọng hay một chuỗi lớn chuyển đổi nó thành chuỗi và thực hiện thay thế (và chuyển đổi lại nếu cần) không nằm trong câu hỏi? – Dukeling

+1

Bạn có thể tạo một 'Matcher' (có thể được tạo trên bất kỳ' CharSequence') và sau đó viết một vòng lặp với 'appendReplacement' và' appendTail' để viết 'replaceAll' của riêng bạn. –

+0

Có nhưng một trong đó sử dụng StringBuffer ... – h22

Trả lời

0

Apache Harmony Matcher source code có vẻ hoàn toàn có thể làm lại được sử dụng với StringBuilder thay vì hiện đang sử dụng StringBuffer, chỉ cần chuyển sang gói khác. Có vẻ như không kéo nhiều phụ thuộc vào nó. Giấy phép Apache ở đầu tệp có thể không tệ ngay cả đối với dự án thương mại.

GNU Classpath mã cũng có thể được sử dụng lại nhưng giấy phép khó khăn hơn (bạn cần xuất bản phiên bản đã thay đổi của Matcher nhưng có lẽ không phải phần còn lại của mã). Tương tự về việc thực hiện của Sun ban đầu có thể được tìm thấy here trong dự án OpenJDK.

3

String.replaceAll chỉ là một phương pháp tiện lợi cho Matcher.replaceAll. Matcher là cách "thực tế" để sử dụng regex trong Java và cho phép nhiều trường hợp sử dụng phức tạp hơn.

Hơn nữa, bất cứ điều gì có thể được thực hiện với phương pháp regex trên String có thể được thực hiện với các phương pháp tương tự trên Matcher. Làm đẹp là công việc Matcher s có nhiều hơn chỉ String s: Matcher s có thể lấy được cho bất kỳ CharSequence (giao diện nào được triển khai bởi StringBuilder, StringBuffer, StringCharBuffer). Vì vậy, bạn có thể chỉ cần thực hiện:

import java.util.regex.*; 

... 

StringBuilder sb = new StringBuilder(); 
sb.append("This works with StringBuffers"); 
Pattern p = Pattern.compile("\\Buffer\\B"); 
Matcher m = p.matcher(sb); 
System.out.println(m.replaceAll("uilder")); 

Sẽ xuất This works with StringBuilders.

Working demo.

+0

Tôi không chắc chắn nếu OP là cho một cái gì đó như thế này kể từ 'm.relaceAll' sẽ sử dụng nội bộ StringBuffer và trả về String với dữ liệu thay thế. Tôi tin rằng OP muốn biết là có một cách để sử dụng StringBuilder thay vì StringBuffer như chúng ta sử dụng nó trong 'Matcher # appendReplacement()' nhưng tôi có thể sai. OP bình luận sẽ tốt hơn ở đây. – Pshemo

+0

@Pshemo ah okay, tôi không biết rằng 'Matcher' sử dụng StringBuffer trong nội bộ. –

+3

Về cơ bản tôi có chữ ký phương thức sau: 'public void replaceAll (trình xây dựng StringBuilder cuối cùng, chuỗi cuối cùng regex, thay thế chuỗi cuối cùng)'. Dữ liệu của người xây dựng nên được sửa đổi mà không phải thực hiện bất kỳ sự phân công lại nào. –

0

Regex không sửa đổi một mutable CharSequence nội bộ. Regex phân tích cú pháp số CharSequence để trả về một String, trong đó String là kết quả. StringBuffer là một ngoại lệ vì có xử lý đặc biệt - như đối với StringBuilderCharSequence, bạn phải sửa đổi nó với kết quả đối sánh.

gì bạn có thể làm thay vì:

// Class 
private static final Pattern MY_PATTERN = Pattern.compile("my|regex"); 

{ // Method 
    StringBuilder builder; 
    // ... 

    Matcher m = MY_PATTERN.matcher(builder); 
    builder.replace(0, builder.length(), m.replaceAll("<b>$0</b>")); 
} 

View a test code demo!