2012-07-25 9 views
15

Nie można dopasować łańcucha zawierającego znaki nowej linii, gdy linia jest otrzymana za pomocą obiektu %n w obiekcie Formatter lub String.format(). Proszę spojrzeć na następujący program:Wyrażenie regularne nie pasuje do znaku nowej linii uzyskanego z obiektu Formatter

public class RegExTest { 

    public static void main(String[] args) { 
    String input1 = String.format("Hallo\nnext line"); 
    String input2 = String.format("Hallo%nnext line"); 
    String pattern = ".*[\n\r].*"; 
    System.out.println(input1+": "+input1.matches(pattern)); 
    System.out.println(input2+": "+input2.matches(pattern)); 
    } 

} 

a jego produkcja:

Hallo 
next line: true 
Hallo 
next line: false 

Co tu się dzieje? Dlaczego drugi ciąg nie pasuje?

Wersja Java to 1.6.0_21.

Odpowiedz

43

Możesz ustawić flagę Pattern.DOTALL, aby dopasować nowe linie do wartości ., ponieważ domyślnie tak się nie dzieje. Dokonuje się tego za pomocą notacji (?s). Tak, to wyrażenie regularne robi to, co chcesz:

String pattern = "(?s).*[\n\r].*"; 
+0

Więc dlaczego pierwszy mecz (Jestem na windows) ? – Axel

+1

Ponadto, możesz chcieć zmienić część '[\ r \ n]' na '\ r? \ N', aby móc dopasować zarówno' \ n' jak i '\ r \ n'. – Keppil

+2

Właśnie się dowiedziałem. W systemie Windows lineend to '\ r \ n'. '\ N' w' input1' nie jest uważany za koniec linii, więc wyrażenie regularne jest zgodne. – Axel

9

na Windows, Java, \n jest LF, \r jest CR i %n jest CRLF. Twój wzór nie pasuje do tego ostatniego.

Od wersji Java 8 można teraz używać w wyrażeniach regularnych \R, aby dopasować dowolną sekwencję końca wiersza.

lineBreak dopasowujący

\R Każda sekwencja LINEBREAK Unicode, jest odpowiednikiem \u000D\u000A|[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]

Przykład:

String pattern = ".*\\R.*"; 
String.format("Hallo\nnext line").matches(pattern); // true 
String.format("Hallo%nnext line").matches(pattern); // true 
String.format("Hallo same line").matches(pattern); // false 
+0

Tak, ". * \ R? \ N. *" Działa, ale nie, jeśli istnieje wiele linii podziału. Teraz używam "(? S). * [\ N \ r]. *". – Axel

Powiązane problemy