String.contains(«.») и Regex оцениваются как false, когда длина последнего слова в строке превышает 41

#java #regex #string

#java #регулярное выражение #строка

Вопрос:

У меня есть программа, которая считывает строку и проверяет ее структуру. Если в строке нет точки, она игнорирует ее и переходит к следующей, в которой есть точка (и если это первая строка с точкой, найденной после той, в которой ее нет, она также игнорирует эту).

Однако я столкнулся с проблемой, когда заметил, что длинные строки игнорируются. Итак, я проверил с помощью консоли, чтобы увидеть, где это происходит, и это показало мне, что строки, в которых последнее слово превышало 41, помечались как «без точек» и, таким образом, игнорировались.

Сначала я использовал регулярное выражение для сопоставления с точкой

 if(errorCount < 1 amp;amp; line.matches("^\s{7}[^.]*$")){ //If a line doesn't have 7 whitespaces    from the start, it's an error, that's why my regex includes that.
  System.out.println("dot1 "   line); 
  pw.println(line);
  noPeriod = true;
  continue;  
}
  

Позже я изменил это, чтобы вместо этого использовать !line.contains(«.») в качестве условия, но происходит то же самое.

Следующая строка вычисляется правильно (точка обнаружена)

77 RESu PIC A(2) VALUE aholaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.

Та же строка с еще одним символом оценивается как «без точек»

77 RESu PIC A(2) VALUE aholaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.

Сначала я подумал, что это проблема с последним словом, содержащим кавычки, но это происходит в любом случае, единственное требование — чтобы длина последнего слова превышала 41. Нет другого условия, которое проверяет, превышает ли последнее слово 42 символа или нет. Кроме того, это происходит специально для последнего слова. Если я удалю пробел между ЗНАЧЕНИЕМ и словом, проблема перестанет появляться. строка типа

77 RESu PIC A(2) VALUEaholaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.

не показывает никаких проблем.

Комментарии:

1. Я проверил все три ваших примера на соответствие вашему регулярному выражению, и все они возвращают false для меня, как и должны. Удаление ‘.’ приводит к тому, что любой из них возвращает true . Я подозреваю, что перед этим у вас должен быть код, который изменяет значение line .

2. С matches() вам не нужно использовать ^ и $, потому что matches() проверяет всю строку. Я сомневаюсь, что это ваша проблема.

Ответ №1:

Давайте рассмотрим ваше регулярное выражение. ^s{7}[^.]*$

  • «^« Сначала вы утверждаете, что позиция соответствия должна начинаться с начала строки.
  • `{7}` тогда, конечно, соответствует пробелу 7 раз.
  • `[^.]*` не соответствует точке.От нуля до бесконечности.это означает, что вы сталкиваетесь с точкой, которую вы пытаетесь сопоставить со следующим символом, который не будет работать. как утверждает якорь, мы должны быть в начале.
  • «$« И, наконец, мы должны соответствовать до конца строки или до разрыва строки в конце строки.
    По состоянию на то, что вы пытаетесь сделать, это убедиться, что вся ваша строка соответствует вашему регулярному выражению. И, очевидно, с точкой это не так. Не может быть ограничения на ввод, которое имеет тенденцию игнорировать ваш ввод, как сказано. Они будут оцениваться с последовательностью, аналогичной приведенной выше. Возможно, это была не ваша проблема. Если вы пересмотрите документацию по регулярным выражениям java или посмотрите на их источник, это полный алгоритм, который, похоже, никоим образом не вызывает такого случайного поведения. Поэтому рекомендуется использовать внешнее программное обеспечение, такое как JRegex, для проверки вашего регулярного выражения перед их использованием, чтобы убедиться, что вы хотите видеть то, что видите.