Ruby / Rails парсинг писем - PullRequest
2 голосов
/ 06 марта 2011

В настоящее время я использую следующее для разбора электронных писем:

  def parse_emails(emails)
    valid_emails, invalid_emails = [], []
    unless emails.nil?
      emails.split(/, ?/).each do |full_email|
        unless full_email.blank?
          if full_email.index(/\<.+\>/)
            email = full_email.match(/\<.*\>/)[0].gsub(/[\<\>]/, "").strip
          else
            email = full_email.strip
          end
          email = email.delete("<").delete(">")
          email_address = EmailVeracity::Address.new(email)
          if email_address.valid?
            valid_emails << email 
          else
            invalid_emails << email
          end
        end
      end                    
    end
    return valid_emails, invalid_emails
  end

Проблема, с которой я сталкиваюсь, связана с электронным письмом:

Bob Smith <bob@smith.com>

Приведенный выше код - удаление БобаСмит и только возвращается bob@smith.

Но то, что я хочу, это хеш FNAME, LNAME, EMAIL.Где fname и lname необязательны, а email - нет.

Какой тип объекта ruby ​​я бы использовал для этого и как бы я создал такую ​​запись в приведенном выше коде?

Спасибо

Ответы [ 3 ]

3 голосов
/ 06 марта 2011

Я закодировал, чтобы она работала, даже если у вас есть такая запись: John Bob Smith Doe <bob@smith.com>

Будет получено:

{:email => "bob@smith.com", :fname => "John", :lname => "Bob Smith Doe" }

def parse_emails(emails)
  valid_emails, invalid_emails = [], []
  unless emails.nil?
    emails.split(/, ?/).each do |full_email|
      unless full_email.blank?
        if index = full_email.index(/\<.+\>/)
          email = full_email.match(/\<.*\>/)[0].gsub(/[\<\>]/, "").strip
          name  = full_email[0..index-1].split(" ")
          fname = name.first
          lname = name[1..name.size] * " "
        else
          email = full_email.strip
          #your choice, what the string could be... only mail, only name?
        end
        email = email.delete("<").delete(">")
        email_address = EmailVeracity::Address.new(email)

        if email_address.valid?
          valid_emails << { :email => email, :lname => lname, :fname => fname} 
        else
          invalid_emails << { :email => email, :lname => lname, :fname => fname}
        end
      end
    end                    
  end
  return valid_emails, invalid_emails 
end
0 голосов
/ 02 ноября 2012

Вы можете использовать rfc822 gem. Содержит регулярное выражение для поиска писем, соответствующих RFC. Вы можете легко дополнить его деталями для поиска имени и фамилии.

0 голосов
/ 17 июля 2012

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

Я не пытаюсь отделить имя от фамилии - слишком проблематично(например, «Мэри Энн Смит» или «Доктор Мэри Смит»), но я исключаю дублирующиеся адреса электронной почты.

def parse_list(list)
  r = Regexp.new('[a-z0-9\.\_\%\+\-]+@[a-z0-9\.\-]+\.[a-z]{2,4}', true)
  valid_items, invalid_items = {}, []

  ## split the list on commas and/or newlines
  list_items = list.split(/[,\n]+/)

  list_items.each do |item|
    if m = r.match(item)
      ## get the email address
      email = m[0]
      ## get everything before the email address
      before_str = item[0, m.begin(0)]
      ## get everything after the email address
      after_str = item[m.end(0), item.length]
      ## enter the email as a valid_items hash key (eliminating dups)
      ## make the value of that key anything before the email if it contains
      ## any alphnumerics, stripping out any angle brackets
      ## and leading/trailing space   
      if /\w/ =~ before_str
        valid_items[email] = before_str.gsub(/[\<\>\"]+/, '').strip
      ## if nothing before the email, make the value of that key anything after
      ##the email, stripping out any angle brackets and leading/trailing space 
      elsif /\w/ =~ after_str
        valid_items[email] = after_str.gsub(/[\<\>\"]+/, '').strip
      ## if nothing after the email either,
      ## make the value of that key an empty string
      else
        valid_items[email] = ''
      end
    else
      invalid_items << item.strip if item.strip.length > 0
    end
  end

  [valid_items, invalid_items]
end

Возвращает хэш с действительными адресами электронной почты в качестве ключей и связанными именами в качестве значений. Любойнедопустимые элементы возвращаются в массиве invalid_items.

См. http://www.regular -expressions.info / email.html для интересного обсуждения регулярных выражений электронной почты.

Я сделалмаленький драгоценный камень из этого в случае, если это могло бы быть полезно кому-то в https://github.com/victorgrey/email_addresses_parser

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