Использование регулярного выражения для фильтрации группы адресов электронной почты в тексте с некоторыми конкретными условиями

Я экспериментирую с регулярным выражением и пытаюсь отфильтровать кучу адресов электронной почты, встроенных в какой-либо текстовый источник. Процесс фильтрации будет зависеть от двух конкретных условий:

  1. Каждое письмо начинается с abc

  2. Обычный шаблон электронной почты, который включает @, за которым следует . и заканчивается конкретно на com

Источник:

sajgvdaskdsdsds[email protected]sdksdhkshdsdk[email protected]wdgjkasdsdad

Pattern1 = "abc[\w\W][@][\w]\.com

код:

public class Test {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {
        boolean found = false;
        String source = "[email protected]@gmail.comwdgjkasdsdad";


        String pattern1 = "abc[\\w\\W]*[@][\\w]*\\.com";

        Pattern p1 = Pattern.compile(pattern1);
        Matcher m1 = p1.matcher(source);
        System.out.println("Source:\t" + source);
        System.out.println("Exprsn:\t" + m1.pattern());
        while (m1.find())
        {
            found = true;
            System.out.println("Pos: " + m1.start() + "\tFound: " + m1.group());
        }
        System.out.println();
        if(!found)
        {
            System.out.println("Nothing found!");
        }

    }

}

Я ожидаю o/p как:

Позиция: 15 Найдено: [email protected]

Поз.: 48 Найдено: [email protected]

Но получаю:

Позиция: 15 Найдено: [email protected]@gmail.com

Если я использую этот Pattern2: abc[\\w]*[@][\\w]*\\.com, то я получаю ожидаемый o/p. Однако дело в том, что адрес электронной почты может содержать символы, отличные от слов, после abc и до @. (Например: [email protected]).

Следовательно, Pattern2 не работает с несловными символами. Итак, я выбрал [\\w\\W]* вместо [\\w]*.

Я также пробовал Pattern3: abc[\\w\\W][@][\\w]\\.com[^.] и все еще не работает.

Пожалуйста, помогите мне, где я делаю неправильно?


person ShashiKanth Chill    schedule 11.02.2018    source источник


Ответы (3)


Операторы регулярных выражений по умолчанию являются жадными, что означает, что они захватят столько строк, сколько смогут. [\w\W]* захватит все промежуточные @ символы, кроме самого последнего.

Либо используйте неохотную форму операторов (например, *? вместо *), либо просто упростите выражение:

abc[^@]*@[^.]+\.com

[^@] возьмет столько символов, которые не являются @, сколько сможет найти. Точно так же [^.] будет соответствовать всему до первой точки.

В качестве альтернативы вы можете использовать неохотные операторы:

abc.*?@.*?\.com
person Mad Physicist    schedule 11.02.2018
comment
Работал как шарм! Спасибо!! Нужно было упростить выражение, используя ^@ и ^. Огромное спасибо! :) - person ShashiKanth Chill; 11.02.2018
comment
Рад, что это помогло. Это первый вопрос регулярного выражения, показывающий много усилий и исследований, которые я видел за долгое время. Так держать - person Mad Physicist; 11.02.2018
comment
Спасибо. Могу я спросить, есть ли шаблоны для того, чтобы сказать что-то вроде этого: найти мне что-то, что имеет ровно n число x в строке? Типа: 11111саксда ‹-- 5 шт. из 1. - person ShashiKanth Chill; 11.02.2018
comment
x{n} должен это сделать - person Mad Physicist; 11.02.2018
comment
Вы также можете сделать x{m, n}, чтобы указать x между mи n разами. - person Mad Physicist; 11.02.2018

Попробуйте исключить '@' из левой части:

"abc[\\w\\W&&[^@]]+@[\\w]+\\.com"

Затем в следующем вводе:

"[email protected]" + 
"[email protected]" + 
"[email protected]"

это соответствует:

[email protected]
[email protected]
[email protected]

Синтаксис [foo&&[^bar]] в регулярном выражении означает: включить все foo, но исключить все bar.


EDIT: шаблон [\\w\\W&&[^@]] немного бессмысленен, потому что он такой же, как [^@]. Однако, если вы хотите ограничить \\w\\W чем-то более значимым, это все равно сработает.

person Andrey Tyukin    schedule 11.02.2018
comment
[\\w\\W&&[^@]] - это просто очень сложный способ сказать [^@], но +1 за то, что показал мне этот синтаксис. Я никогда не видел его раньше. - person Mad Physicist; 11.02.2018
comment
Ты прав. [\\w\\W] является избыточным для [^@]. Понял правильно, большое спасибо! :) - person ShashiKanth Chill; 11.02.2018
comment
@MadPhysicist Спасибо. Я решил оставить все как есть, потому что, например, часть \\w\\W может быть заменена классом символов без пробелов \\S, так что шаблон становится [\\S&&[^@]], что является более значимым и более конкретным, чем просто [^@]. - person Andrey Tyukin; 11.02.2018

В вашем первом классе символов - \\w включает все слово-символы , [a-zA-Z_0-9]. \\W — это всего лишь дополнение к этому, так что я могу сопоставить их с чем угодно. В идеале вы должны использовать белый список символов, которые вы ожидаете здесь (\n, вероятно, не разрешено!), но ключевой момент в том, что вам определенно не нужен @, поэтому это даст вам два совпадения:

"abc[^@]*[@][\\w]*\\.com"

Я бы предложил, чтобы другие квадратные скобки были излишними, поэтому их следует удалить, и что во второй группе действительно должен быть хотя бы один символ. Это оставит вас с:

"abc[^@]*@\w+\.com"

person hugh    schedule 11.02.2018
comment
Спасибо. В основном я рассматривал тему метасимволов и думал с этой точки зрения ... поэтому не думал о ^@. Я исправил это, спасибо! :) - person ShashiKanth Chill; 11.02.2018