Регулярное выражение для обнаружения одной из нескольких строк - PullRequest
42 голосов
/ 10 марта 2009

У меня есть список адресов электронной почты, принадлежащих нескольким доменам. Мне бы хотелось, чтобы регулярное выражение совпадало с адресами, принадлежащими трем конкретным доменам (для этого примера: foo, bar и & baz)

Таким образом, они будут соответствовать:

  1. а @ Foo
  2. а @ бар
  3. б @ Баз

Это не будет:

  1. а @ Fnord

В идеале, они тоже не будут совпадать (хотя это не критично для данной конкретной проблемы):

  1. а @ Foobar
  2. б @ foofoo

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

Ответы [ 7 ]

101 голосов
/ 11 марта 2009

Используйте символ трубы для обозначения «или»:

/a@(foo|bar|baz)\b/

Если вам не нужна группа захвата, используйте символ группировки без захвата:

/a@(?:foo|bar|baz)\b/

(Конечно, я предполагаю, что "a" в порядке в начале адреса электронной почты! Вы должны заменить это подходящим регулярным выражением.)

10 голосов
/ 11 марта 2009
^(a|b)@(foo|bar|baz)$

если у вас есть строго определенный список. Начальный и конечный символы будут искать только эти три строки.

4 голосов
/ 11 марта 2009

Использование:

/@(foo|bar|baz)\.?$/i

Обратите внимание на отличия от других ответов:

  • \.? - совпадение 0 или 1 точки, если домены в адресе электронной почты "полностью квалифицированы"
  • $ - чтобы указать, что строка должна заканчиваться этой последовательностью,
  • /i - сделать тестовый регистр нечувствительным.

Обратите внимание, это предполагает, что каждый адрес электронной почты находится на отдельной строке.

Если сопоставляемая строка может находиться где-либо в строке, тогда отбросьте $ и замените его на \s+ (что соответствует одному или нескольким символам пробела)

2 голосов
/ 11 марта 2009

должно быть более общим, a не должно учитываться, хотя @ должно.

/@(foo|bar|baz)(?:\W|$)/

Здесь является хорошим справочником по регулярным выражениям.

edit: изменить окончание, чтобы разрешить конец шаблона или разрыв слова. теперь предположим, что foo / bar / baz являются полными доменными именами.

1 голос
/ 11 марта 2009

Если предыдущий (и логичный) ответит о '|' не устраивает вас, посмотрите на

http://metacpan.org/pod/Regex::PreSuf

описание модуля: создание регулярных выражений из списков слов

0 голосов
/ 11 марта 2009

Хорошо, я знаю, что вы просили ответить на регулярное выражение. Но не задумывались ли вы о разделении строки символом '@'? принимая значение второго массива (домен) и делать простой тест на совпадение

if (splitString[1] == "foo" && splitString[1] == "bar" && splitString[1] == "baz")
{
   //Do Something!
}

Мне кажется, что RegEx - это перебор. Конечно, я предполагаю, что ваше дело действительно так просто, как вы перечислили.

0 голосов
/ 11 марта 2009

Вам не нужно регулярное выражение, чтобы найти, содержит ли строка хотя бы один из заданного списка подстрок. В Python:

def contain(string_, substrings):
    return any(s in string_ for s in substrings)

Выше приведено медленно для большой string_ и многих подстрок. GNU fgrep может эффективно искать несколько шаблонов одновременно.

Использование регулярных выражений

import re

def contain(string_, substrings):
    regex = '|'.join("(?:%s)" % re.escape(s) for s in substrings)
    return re.search(regex, string_) is not None

1012 * Относящиеся * Алгоритм сопоставления с несколькими шаблонами (MSMPMA) [pdf]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...