Có phương pháp API nào trả về tất cả các phần tử (có thể chồng chéo) phù hợp với cụm từ thông dụng không? Ví dụ: Tôi có một chuỗi văn bản: String t = 04/31 412-555-1235;
và tôi có mẫu: Pattern p = new Pattern("\\d\\d+");
khớp với chuỗi có từ hai ký tự trở lên.Tất cả các chất nền chồng chéo phù hợp với một regex java
Các kết quả phù hợp tôi nhận được là: 04, 31, 412, 555, 1235.
Làm cách nào để nhận các kết quả trùng lặp?
Tôi muốn mã trở lại: 04, 31, 41, 412, 12, 55, 555, 55, 12, 123, 1235, 23, 235, 35.
Về mặt lý thuyết chúng ta có thể - có một thuật toán rõ ràng là O(n^2)
liệt kê và kiểm tra tất cả các chất nền dựa vào mẫu.
EDIT
Thay vì liệt kê tất cả các chuỗi con, nó là an toàn hơn để sử dụng phương pháp region(int start, int end)
trong Matcher
. Việc kiểm tra mẫu dựa trên chuỗi con được tách riêng, có thể thay đổi kết quả của kết quả phù hợp (ví dụ: nếu có một nhóm không bắt giữ hoặc kiểm tra ranh giới từ ở đầu/cuối mẫu).
EDIT 2
Trên thực tế, không rõ liệu region()
làm những gì bạn mong đợi cho trận zero-chiều rộng. Đặc điểm kỹ thuật là mơ hồ, và các thí nghiệm mang lại kết quả đáng thất vọng.
Ví dụ:
String line = "xx90xx";
String pat = "\\b90\\b";
System.out.println(Pattern.compile(pat).matcher(line).find()); // prints false
for (int i = 0; i < line.length(); ++i) {
for (int j = i + 1; j <= line.length(); ++j) {
Matcher m = Pattern.compile(pat).matcher(line).region(i, j);
if (m.find() && m.group().size == (j - i)) {
System.out.println(m.group() + " (" + i + ", " + j + ")"); // prints 90 (2, 4)
}
}
}
Tôi không chắc chắn những gì các giải pháp thanh lịch nhất là. Một cách tiếp cận sẽ là lấy một chuỗi con là line
và đệm bằng các ký tự ranh giới thích hợp trước khi kiểm tra xem các kết quả trùng khớp pat
có phù hợp hay không.
EDIT 3
Dưới đây là giải pháp đầy đủ mà tôi đã đưa ra. Nó có thể xử lý các mẫu có độ rộng 0, các đường biên, vv trong biểu thức chính quy ban đầu. Nó xem xét tất cả các chuỗi của chuỗi văn bản và kiểm tra xem biểu thức chính quy chỉ khớp với vị trí cụ thể bằng cách đệm mẫu với số ký tự đại diện thích hợp ở đầu và cuối. Nó dường như làm việc cho các trường hợp tôi đã thử - mặc dù tôi đã không làm thử nghiệm rộng rãi. Nó chắc chắn kém hiệu quả hơn nó có thể.
public static void allMatches(String text, String regex)
{
for (int i = 0; i < text.length(); ++i) {
for (int j = i + 1; j <= text.length(); ++j) {
String positionSpecificPattern = "((?<=^.{"+i+"})("+regex+")(?=.{"+(text.length() - j)+"}$))";
Matcher m = Pattern.compile(positionSpecificPattern).matcher(text);
if (m.find())
{
System.out.println("Match found: \"" + (m.group()) + "\" at position [" + i + ", " + j + ")");
}
}
}
}
EDIT 4
Dưới đây là một cách tốt hơn để làm điều này: https://stackoverflow.com/a/11372670/244526
EDIT 5
Thư viện JRegex hỗ trợ việc tìm kiếm tất cả các chuỗi con chồng chéo phù hợp với một regex java (mặc dù có vẻ như không được cập nhật trong một thời gian).Cụ thể, số documentation on non-breaking search chỉ định:
Sử dụng tìm kiếm không phá vỡ bạn có thể tìm thấy tất cả các mẫu có thể có của mẫu , bao gồm cả những mẫu được giao nhau hoặc lồng nhau. Đây là đạt được bằng cách sử dụng phương thức của Matcher() thay vì tìm()
chỉ cần thực hiện lặp lại sau regex cho tất cả 3 hoặc nhiều ký tự kết quả –
http://regexlib.com/ có thể là một nơi tốt để thực hiện một số thao tác đào. –
@ Ωmega Đang cố gắng hết sức, nhưng mở ra phản hồi không hữu ích. Chúc mừng. –