Почему не срабатывает регулярное выражение после считывания текста из файла в строку?

Есть файл с текстом, к примеру 1.txt
Текст в файле ---> "фффффффф в ррррр ллллл вавава на."

//Считываю текст в переменную  

    String textFromFile = Files.readString(Path.of("1.txt"), StandardCharsets.UTF_8);  

//Вывожу текст в консоль чтобы убедиться что все считано  

    System.out.println(textFromFile); // фффффффф в ррррр ллллл вавава на.

//Проверяю регулярным выражением вхождение подстроки  

    System.out.println(textFromFile.matches("(.*) в (.*)")); // false
    System.out.println(textFromFile.matches("(.*)\\sв\\s(.*)")); // false
    System.out.println(textFromFile.matches(".*в.*")); // false

//Подставляю вместо переменной непосредственно сам текст  

    System.out.println("фффффффф в ррррр ллллл вавава на.".matches("(.*) в (.*)")); // true
    System.out.println("фффффффф в ррррр ллллл вавава на.".matches("(.*)\\sв\\s(.*)")); // true
    System.out.println("фффффффф в ррррр ллллл вавава на.".matches(".*в.*")); // true

Почему проверка переменной на вхождение подстроки дает false?
Куда смотреть, где почитать, что упускаю?


Ответы (1 шт):

Автор решения: Nowhere Man

Скорее всего, в конце строки стоит символ перевода строки \n или \r\n.

Метод Files::readString считывает весь файл целиком в одну строку, а метод String::matches точно так же сравнивает с паттерном всю строку, при этом по умолчанию символ . не включает символы окончания строк.

Нужно либо обрезать пробельные символы при помощи String::trim, либо убрать их при помощи String::replaceAll, либо изменить паттерн, чтобы включить режим Pattern.DOTALL, например, при помощи флажка (?s):

System.out.println("'" + textFromFile + "'");
// -> 'фффффффф в ррррр ллллл вавава на.
// -> '
System.out.println(textFromFile.trim().matches("(.*) в (.*)")); 
// -> true
System.out.println(textFromFile.replaceAll("\\R", "").matches("(.*) в (.*)")); 
// -> true
System.out.println(textFromFile.matches("(?s)(.*) в (.*)")); 
// -> true
→ Ссылка