28

I am working on an application where I need to pass on the anything before "@" sign from the user's email address as his/her first name and last name. For example if the user has an email address "user@example.com" than when the user submits the form I remove "@example.com" from the email and assign "user" as the first and last name.

I have done research but was not able to find a way of doing this in Ruby. Any suggestions ??

eugen
  • 8,916
  • 11
  • 57
  • 65
Smoke
  • 1,052
  • 1
  • 10
  • 24
  • Why are you using a regular expression for this? http://stackoverflow.com/questions/201323/what-is-the-best-regular-expression-for-validating-email-addresses – Andrew Grimm Aug 10 '11 at 00:19

5 Answers5

52

You can split on "@" and just use the first part.

email.split("@")[0]

That will give you the first part before the "@".

J Lundberg
  • 2,313
  • 2
  • 20
  • 23
48

To catch anything before the @ sign:

my_string = "user@example.com"
substring = my_string[/[^@]+/]
# => "user"
Dylan Markow
  • 123,080
  • 26
  • 284
  • 201
  • +1 for RegEx. Gives you more versatility and helps you avoid the dangerous habit of referencing a literal index position. – Ishpeck Aug 09 '11 at 19:20
  • 8
    @Ishpeck: How much versatility do you need? You're splitting at string at the `@` sign. It's not a particularly volatile task, and adding the complexity of a whole Regexp FSM to the mix doesn't seem to make it any less so. – Chuck Aug 09 '11 at 19:25
  • You could use the regex to sanitize the data for, say, a database query. http://xkcd.com/327/ – Ishpeck Aug 09 '11 at 19:36
  • 1
    I agree that `#split` is probably the easier answer for this specific scenario -- but I don't think a RegExp is overly complex – Dylan Markow Aug 09 '11 at 19:46
13

Just split at the @ symbol and grab what went before it.

string.split('@')[0]
Chuck
  • 234,037
  • 30
  • 302
  • 389
8

The String#split will be useful. Given a string and an argument, it returns an array splitting the string up into separate elements on that String. So if you had:

e = test@testing.com
e.split("@")
 #=> ["test", "testing.com"]

Thus you would take e.split("@")[0] for the first part of the address.

Pygmalion
  • 692
  • 5
  • 19
1

use gsub and a regular expression

first_name = email.gsub(/@[^\s]+/,"")



irb(main):011:0> Benchmark.bmbm do |x|
irb(main):012:1* email = "user@domain.type"
irb(main):013:1> x.report("split"){100.times{|n| first_name = email.split("@")[0]}}
irb(main):014:1> x.report("regex"){100.times{|n| first_name = email.gsub(/@[a-z.]+/,"")}}
irb(main):015:1> end
Rehearsal -----------------------------------------
split   0.000000   0.000000   0.000000 (  0.000000)
regex   0.000000   0.000000   0.000000 (  0.001000)
-------------------------------- total: 0.000000sec

            user     system      total        real
split   0.000000   0.000000   0.000000 (  0.001000)
regex   0.000000   0.000000   0.000000 (  0.000000)
=> [#<Benchmark::Tms:0x490b810 @label="", @stime=0.0, @real=0.00100016593933105, @utime=0.0, @cstime=0.0, @total=0.0, @cutime=0.0>, #<Benchmark::Tms:0x4910bb0 @
label="", @stime=0.0, @real=0.0, @utime=0.0, @cstime=0.0, @total=0.0, @cutime=0.0>]
Tim Hoolihan
  • 12,316
  • 3
  • 41
  • 54
  • People go to regular expressions far too readily. They should *not* be your first choice for splitting a string. – user229044 Aug 09 '11 at 19:18
  • You may want to look at the benchmark I added, note the final answer not the rehearsal. Assuming the regex engine is already spun up, it's faster. – Tim Hoolihan Aug 09 '11 at 19:53
  • I should add that there is no reason to optimize such a statement unless it's in a loop. network latency is a far bigger deal than how you parse / validate a parameter. I just wanted to make the point since you posted a generalized and preachy comment – Tim Hoolihan Aug 09 '11 at 19:55
  • 2
    Benchmarking this is kind of insane, and using only 100 iterations is incredibly bogus. Regardless, not only does `email[0,email.index('@')]` blow both of your benchmarked solutions out of the water, it is obvious and straight forward which is far more important. Finding a substring by replacing the non-substring stuff with a empty string via regular expression is about as round-about a solution as you can get. Regular expression isn't for this, you're misusing it. – user229044 Aug 10 '11 at 04:21
  • Also note that your regular expression breaks when the domain portion includes hyphens or digits, both of which are valid. You could add them to the pattern, but the point is you shouldn't have to. You started out trying to find the characters before `@`, and suddenly you're writing a regular expression to validate domain names. This is what happens when you try to make regular expressions the answer to every trivial problem. – user229044 Aug 10 '11 at 04:27
  • @TimHoolihan let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/2325/discussion-between-meagar-and-tim-hoolihan) – user229044 Aug 10 '11 at 14:15