• ,

Уровень 22. Вопросы.

Регулярные выражения, примеры
Java Multithreading
2 уровень, 11 лекция

В лекции говорится что:
В регулярных выражениях символы «[ ] \ / ^ $. |? * + ( ) { }» имеют специальное значение.
Как и в Java их необходимо экранировать.
Если мы хотим описать, что строка должна состоять из трех символов «?», то нельзя писать так: ?{3}, т.к. символ «?» является управляющим. Надо сделать так: \?{3}

Вопрос: Почему в примере экранируется только символ «?» и не экранируются символы фигурных скобок «{ }»?

Помогите с regexp пожалуйста. level22.lesson13.task03

Вроде бы все описал правильно но что-то явно не учитываю, но что, и как это описать не знаю уже.
если есть мысли то буду рад любой помощи.
Вот код который написал.
Критика тоже приветствуется.
package com.javarush.test.level22.lesson13.task03;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/* Проверка номера телефона
Метод checkTelNumber должен проверять, является ли аргумент telNumber валидным номером телефона.
Критерии валидности:
1) если номер начинается с '+', то он содержит 12 цифр
2) если номер начинается с цифры или открывающей скобки, то он содержит 10 цифр
3) может содержать 0-2 знаков '-', которые не могут идти подряд
4) может содержать 1 пару скобок '(' и ')'  , причем если она есть, то она расположена левее знаков '-'
5) скобки внутри содержат четко 3 цифры
6) номер не содержит букв
7) номер заканчивается на цифру

Примеры:
+380501234567 - true
+38(050)1234567 - true
+38050123-45-67 - true
050123-4567 - true
+38)050(1234567 - false
+38(050)1-23-45-6-7 - false
050ххх4567 - false
050123456 - false
(0)501234567 - false
*/
public class Solution {
    public static void main(String[] args) // это при проверке убираю.
    {
        System.out.println(checkTelNumber("+123456789012"));
    }
    public static boolean checkTelNumber(String telNumber) {
        if (telNumber.isEmpty()) return false;
        char last = telNumber.charAt(telNumber.length() - 1);
        if (!Character.isDigit(last)) return false;
        Pattern p = Pattern.compile("[a-zA-Zа-яА-Я]");
        Matcher m = p.matcher(telNumber);
        if (m.find()) return false;

        if (telNumber.matches("^\\+\\d{13,}$")) return false;
        if (telNumber.matches("^\\d{0,9}$")) return false;
        if (telNumber.matches("^\\+\\d{0,10}\\D\\d{0,10}$")) return false;


        if (telNumber.charAt(0) == '+') if (!telNumber.matches("^\\+\\d{0,5}\\-?(\\({0,1}\\d{3}\\){0,1})\\d?\\-?\\d{3,4}\\-?\\d{0,2}\\-?\\d{0,2}$")) return false;
        char first = telNumber.charAt(0);
        if (telNumber.charAt(0) == '(' || Character.isDigit(first)) if (!telNumber.matches("^\\d{0,2}\\-?\\({0,1}(\\d{3})\\){0,1}\\d{2,5}\\-?\\d{0,3}\\-?\\d{0,2}")) return false;
        return true;
    }
}

level19.lesson05.task02 не проходит тестирование на сервере

package com.javarush.test.level19.lesson05.task02;
/* Считаем слово
Считать с консоли имя файла.
Файл содержит слова, разделенные знаками препинания.
Вывести в консоль количество слов "world", которые встречаются в файле.
Закрыть потоки. Не использовать try-with-resources
*/
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Solution {
    public static void main(String[] args) throws IOException
    {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String fileName = reader.readLine();
        reader.close();
        reader = new BufferedReader(new FileReader(fileName));
        Pattern pattern = Pattern.compile("\\bworld\\b");
        int counter = 0;
        while (reader.ready())
        {
            String s = reader.readLine();
            Matcher matcher = pattern.matcher(s);
            while (matcher.find())
                counter++;
        }
        reader.close();
        System.out.println(counter);
    }
}


Не могу понять, в чем ошибка. На своих файлах тестировал, вывод правильный. Может кто указать, на что обратить внимание?
Обрабатывать исключения вместо пробрасывания пробовал, тоже не проходит.
  • ,

Регулярные выражения в Java

RegEx

Регулярное выражение это своего рода шаблон, который может быть применен к тексту (String, в Java). Java предоставляет пакет java.util.regex для сопоставления с регулярными выражениями. Регулярные выражения очень похожи на язык программирования Perl и очень просты в освоении.
Регулярное выражение или соответствует тексту (его части) или нет.
* Если регулярное выражение совпадает с частю текста, то мы можем найти еe.
** Если регулярное выражение составное, то мы можем легко выяснить, какая часть регулярного выражения совпадает с какой частью текста.

Первый пример
Регулярное выражение "[a-z] +" соответствует всем строчныем буквам в тексте.
[a-z] означает любой символ от a до z включительно, и + означает «один или более» символов.

Предположим, что мы поставляем строку «code 2 learn java tutorial ».

Как это сделать в Java

Во-первых, вы должны составить шаблон:
import java.util.regex.*;
Pattern p = Pattern.compile(“[a-z]+”);

Далее вы должны создать matcher для текста, отправив сообщение на схеме:
Matcher m = p.matcher(“code 2 learn java tutorial”);


ПРИМЕЧАНИЕ:
Ни Pattern ни Matcher не имеют конструкторов, мы создаем их с помощью методов класса Pattern.

Pattern Class: Объект класса составляет представление регулярного выражения. Класс Pattern не предусматривает никаких публичных конструкторов. Чтобы создать шаблон, необходимо сначала вызвать один из публичных статических методов, которые затем возвращают объект класса Pattern. Эти методы принимают регулярное выражение в качестве аргумента.

Matcher Class: Объект «Искатель» является двигателем, который интерпретирует шаблон и выполняет операции сопоставления с входной строкой. Как и Pattern класс, Matcher не имеет публичных конструкторов. Вы получаете объект Matcher вызовом метода matcher, на объекте класса Pattern.

После того как мы выполнили эти шаги, и теперь у нас есть экземпляр класса Matcher m, и теперь мы можем проверить, был найден шаблон или нет, и если да, то в какой позиции, и т.д.

m.matches() возвращает true, если шаблон соответствует всей строке, иначе false.
m.lookingAt() возвращает true, если шаблон соответствует началу строки, и false в противном случае.
m.find () возвращает true, если шаблон совпадает с любой частью текста.

Находим совпадение

После успешного сопостовления, m.start() вернет индекс первого символа, совпавшего и m.end() вернет индекс последнего совпавшего символа, плюс один.
  • ,

Как разбить строку

Имеется строка, разделённая пробелами. Например:
String s = "hello world";
// Разбиваем
String[] split = s.split(" ");
// split[0] = "hello"
// split[1] = "world"

Данный код прекрасно работает, но стоит нам только добавить лишний пробел, как всё ломается. Не беда, подберём другую регулялку:
String s = "hello   world     ";
// Разбиваем
String[] split = s.split(" +");
// split[0] = "hello"
// split[1] = "world"

Однако этот код снова не рабочий. Если назойливый пробел поставить в начало строки, то всё снова сломается:
String s = " hello world";
// Разбиваем
String[] split = s.split(" +");
// split[0] = ""
// split[1] = "hello"
// split[2] = "world"

Прошу вашей помощи. Как дальше?

Регулярные выражения: найти слово/часть слова

Если требуется найти слово или подстроку, хорошим решением будет использовать оператор контроля из инструментария регулярных выражений. Он незаменим в случаях, если вам требуется найти что-нибудь, следующее за чем-нибудь еще.