Pertanyaan Penggunaan pemindai Java dengan pola \ R (masalah dengan batas buffer)


Ringkasan bisnis plan: Apakah ada batasan / masalah yang diketahui \R (atau pola regex) lainnya di Java Scanner (terutama mengenai kondisi batas buffer internal)?

Detail: Karena saya ingin melakukan pencocokan pola multi-garis pada file input multi-platform yang potensial, saya menggunakan pola dengan \R, yang menurut Pattern javadoc adalah:

Urutan linebreak Unicode apa pun, setara dengan    \u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]

Bagaimanapun, saya perhatikan di salah satu file pengujian saya bahwa loop yang seharusnya mem-parse blok hex-dump dipotong pendek. Setelah beberapa debugging, saya perhatikan bahwa garis yang diakhiri adalah ujung buffer internal Scanner.

Berikut adalah program tes yang saya tulis untuk menyimulasikan situasi:

public static void main(String[] args) throws IOException {
    testString(1);
    testString(1022);
}

private static void testString(int prefixLen) {
    String suffix = "b\r\nX";
    String buffer = new String(new char[prefixLen]).replace("\0", "a") + suffix;

    Scanner scanner = new Scanner(buffer);
    String pattern = "b\\R";
    System.out.printf("=================\nTest String (Len=%d): '%s'\n'%s' found with horizon=0 (w/o bound): %s\n", buffer.length(), convertLineEndings(
        buffer), pattern, convertLineEndings(scanner.findWithinHorizon(pattern, 0)));
    System.out.printf("'X' found with horizon=1: %b\n", scanner.findWithinHorizon("X", 1) != null);
    scanner.close();
}

private static String convertLineEndings(String string) {
    return string.replaceAll("\\n", "\\\\n").replaceAll("\\r", "\\\\r");
}

... yang menghasilkan output ini (diedit untuk pemformatan / keringkasan):

=================
Test String (Len=5): 'ab\r\nX'
'b\R' found with horizon=0 (w/o bound): b\r\n
'X' found with horizon=1: true
=================
Test String (Len=1026): 'a ... ab\r\nX'
'b\R' found with horizon=0 (w/o bound): b\r
'X' found with horizon=1: false

Bagi saya, ini terlihat seperti bug! Saya pikir pemindai harus sesuai dengan itu suffix dengan pola yang sama independen dari mana mereka muncul di input teks (asalkan prefix tidak terlibat dengan pola). (Saya juga menemukan mungkin relevan Buka JDK Bugs 8176407, dan 8072582, tapi ini dengan Oracle JDK 8u111 biasa).

Tapi saya mungkin melewatkan beberapa rekomendasi mengenai pemindai atau yang khusus \R penggunaan pola (atau itu Buka JDK, dan Oracle memiliki identik (??) implementasi untuk kelas yang relevan di sini?) ... maka pertanyaannya!


10
2018-03-02 14:07


asal


Jawaban:


Dua saran:

Saya pikir Anda harus menguji X dengan cara itu:

System.out.printf("'X' found with horizon=1: %b\n", 
    scanner.findWithinHorizon("X", prefixLen) != null);

(Karena apa pun selain 0 sebagai parameter horizon membatasi pencarian ke sejumlah karakter tertentu. Itu sudah dalam nama metode. Cakrawala sejauh metodenya melihatnya.)

Mungkin ada masalah dengan pengkodean file Anda. Pemindai Anda mungkin memilih penyandian default yang salah. Cobalah sesuatu di sepanjang garis itu:

new Scanner(file, "utf-8");

0
2018-03-05 00:39