Tôi luôn nghĩ rằng việc xác nhận trong regex-API của Java (và nhiều ngôn ngữ khác cho vấn đề đó) phải có độ dài hiển nhiên. Vì vậy, số lượng định lượng STAR và PLUS không được phép bên trong nhìn sau.Regex nhìn đằng sau mà không có độ dài tối đa rõ ràng trong Java
Các tuyệt vời trực tuyến tài nguyên regular-expressions.info dường như để xác nhận (một số) giả định của tôi:
"[...] Java có điều một bước xa hơn bằng cách cho phép lặp lại hữu hạn Bạn vẫn không thể sử dụng các ngôi sao. hoặc cộng, nhưng bạn có thể sử dụng dấu hỏi và dấu ngoặc nhọn với tham số max quy định. Java công nhận một thực tế rằng lặp lại hữu hạn có thể được viết lại như một thay đổi luân phiên các chuỗi với khác nhau, nhưng độ dài cố định. Thật không may, JDK 1.4 và 1.5 có một số lỗi khi bạn sử dụng thay đổi bên trong lookbehind. Những đã được sửa trong JDK 1.6. [...]"
Sử dụng dấu ngoặc nhọn làm việc miễn là tổng chiều dài của hàng loạt các nhân vật bên trong nhìn đằng sau là nhỏ hơn hoặc bằng Integer.MAX_VALUE Vì vậy. những regexes là hợp lệ:
"(?<=a{0," +(Integer.MAX_VALUE) + "})B"
"(?<=Ca{0," +(Integer.MAX_VALUE-1) + "})B"
"(?<=CCa{0," +(Integer.MAX_VALUE-2) + "})B"
Nhưng đây không phải là:
"(?<=Ca{0," +(Integer.MAX_VALUE) +"})B"
"(?<=CCa{0," +(Integer.MAX_VALUE-1) +"})B"
Tuy nhiên, tôi không hiểu thứ e sau:
Khi tôi chạy thử nghiệm bằng cách sử dụng * và + lượng hóa bên trong một nhìn đằng sau, mọi việc suôn sẻ (xem ra Test 1 và thử nghiệm 2).
Nhưng, khi tôi thêm một nhân vật duy nhất tại sự bắt đầu của nhìn đằng sau từ Test 1 và thử nghiệm 2, nó phá vỡ (xem ra thử nghiệm 3).
Làm tham lam * từ Kiểm tra 3 miễn cưỡng không có hiệu lực, nó vẫn bị ngắt (xem Kiểm tra 4).
Đây là khai thác thử nghiệm:
public class Main {
private static String testFind(String regex, String input) {
try {
boolean returned = java.util.regex.Pattern.compile(regex).matcher(input).find();
return "testFind : Valid -> regex = "+regex+", input = "+input+", returned = "+returned;
} catch(Exception e) {
return "testFind : Invalid -> "+regex+", "+e.getMessage();
}
}
private static String testReplaceAll(String regex, String input) {
try {
String returned = input.replaceAll(regex, "FOO");
return "testReplaceAll : Valid -> regex = "+regex+", input = "+input+", returned = "+returned;
} catch(Exception e) {
return "testReplaceAll : Invalid -> "+regex+", "+e.getMessage();
}
}
private static String testSplit(String regex, String input) {
try {
String[] returned = input.split(regex);
return "testSplit : Valid -> regex = "+regex+", input = "+input+", returned = "+java.util.Arrays.toString(returned);
} catch(Exception e) {
return "testSplit : Invalid -> "+regex+", "+e.getMessage();
}
}
public static void main(String[] args) {
String[] regexes = {"(?<=a*)B", "(?<=a+)B", "(?<=Ca*)B", "(?<=Ca*?)B"};
String input = "CaaaaaaaaaaaaaaaBaaaa";
int test = 0;
for(String regex : regexes) {
test++;
System.out.println("********************** Test "+test+" **********************");
System.out.println(" "+testFind(regex, input));
System.out.println(" "+testReplaceAll(regex, input));
System.out.println(" "+testSplit(regex, input));
System.out.println();
}
}
}
Sản lượng:
********************** Test 1 **********************
testFind : Valid -> regex = (?<=a*)B, input = CaaaaaaaaaaaaaaaBaaaa, returned = true
testReplaceAll : Valid -> regex = (?<=a*)B, input = CaaaaaaaaaaaaaaaBaaaa, returned = CaaaaaaaaaaaaaaaFOOaaaa
testSplit : Valid -> regex = (?<=a*)B, input = CaaaaaaaaaaaaaaaBaaaa, returned = [Caaaaaaaaaaaaaaa, aaaa]
********************** Test 2 **********************
testFind : Valid -> regex = (?<=a+)B, input = CaaaaaaaaaaaaaaaBaaaa, returned = true
testReplaceAll : Valid -> regex = (?<=a+)B, input = CaaaaaaaaaaaaaaaBaaaa, returned = CaaaaaaaaaaaaaaaFOOaaaa
testSplit : Valid -> regex = (?<=a+)B, input = CaaaaaaaaaaaaaaaBaaaa, returned = [Caaaaaaaaaaaaaaa, aaaa]
********************** Test 3 **********************
testFind : Invalid -> (?<=Ca*)B, Look-behind group does not have an obvious maximum length near index 6
(?<=Ca*)B
^
testReplaceAll : Invalid -> (?<=Ca*)B, Look-behind group does not have an obvious maximum length near index 6
(?<=Ca*)B
^
testSplit : Invalid -> (?<=Ca*)B, Look-behind group does not have an obvious maximum length near index 6
(?<=Ca*)B
^
********************** Test 4 **********************
testFind : Invalid -> (?<=Ca*?)B, Look-behind group does not have an obvious maximum length near index 7
(?<=Ca*?)B
^
testReplaceAll : Invalid -> (?<=Ca*?)B, Look-behind group does not have an obvious maximum length near index 7
(?<=Ca*?)B
^
testSplit : Invalid -> (?<=Ca*?)B, Look-behind group does not have an obvious maximum length near index 7
(?<=Ca*?)B
^
Câu hỏi của tôi có thể rõ ràng, nhưng tôi vẫn sẽ hỏi nó: bất cứ ai có thể giải thích cho tôi tại sao Test 1 và không thành công và Kiểm tra 3 và không? Tôi đã mong đợi tất cả họ thất bại, không phải một nửa trong số họ làm việc và một nửa trong số họ thất bại.
Cảm ơn.
PS. Tôi đang sử dụng: Phiên bản Java 1.6.0_14
Nó không xảy ra với tôi để xem xét nguồn gốc của mẫu ... Silly me. Cảm ơn bạn! Nó làm cho cảm giác hoàn hảo ngay bây giờ. –
Một trong nhiều lý do tôi không thể sống mà không có Eclipse là ngón tay bấm ctrl ngứa của tôi (nếu bạn không sử dụng Eclipse, có nghĩa là "mở tệp nguồn nơi tên này được xác định"). –
Cảm ơn, tôi chưa bao giờ gặp khó khăn để đính kèm nguồn vào Eclipse. Bây giờ tôi sẽ làm như vậy. Cảm ơn. –