0
@message_to = 'bob@google.com'

@cleaned = @message_to.match(/^(.*)+@/)

@cleaned is returning bob@, where I want it to return just bob. Am I doing the regex right with ruby?

Thanks

mu is too short
  • 426,620
  • 70
  • 833
  • 800
AnApprentice
  • 108,152
  • 195
  • 629
  • 1,012
  • 2
    I think regex and email addresses are some sort of gateway-drug-combination for developers. This is a worthy SO question and discussion about the pair: [Why are people using regexp for email and other complex validation?](http://stackoverflow.com/questions/211842/why-are-people-using-regexp-for-email-and-other-complex-validation) – the Tin Man Feb 28 '11 at 04:24
  • @the Tin Man: All programmers are really failed wizards that would rather be casting spells, regular expressions smell like incantations so there's a natural affinity for them. – mu is too short Mar 01 '11 at 06:57
  • @mu is too short, LOL. Yes, very possibly. I always thought it was a macho thing. – the Tin Man Mar 01 '11 at 23:13

6 Answers6

5

No need much regular expression

>> @message_to = "bob@google.com"
=> "bob@google.com"
>> @message_to.split("@",2)
=> ["bob", "google.com"]
>> @message_to.split("@",2)[0] if @message_to["@"]
=> "bob"
>>
kurumi
  • 25,121
  • 5
  • 44
  • 52
  • 2
    +1: People do tend to get fixated on using regexes for everything, basic string mangling shouldn't be overlooked. – mu is too short Feb 28 '11 at 02:11
  • 1
    +1 It's the old "when you have a hammer everything looks like a nail." situation. Regex is a powerful tool, but I find it usually contributes to confusing code, rather than making it clearer, cleaner, and more maintainable. – the Tin Man Feb 28 '11 at 03:10
2

You want this:

@cleaned = @message_to.match(/^(.*)+@/)[1]

match returns a MatchData object and the string version of that is the entire match, the captured groups are available starting at index 1 when you treat the MatchData as an array.

I'd probably go with something more like this though:

@cleaned = @message_to.match(/^([^@]+)@/)[1]
mu is too short
  • 426,620
  • 70
  • 833
  • 800
1

An even shorter code than mu_is_too_short would be:

@cleaned = @message_to[/^([^@]+)@/, 1]

The String#[] method can take a regular expression.

mu is too short
  • 426,620
  • 70
  • 833
  • 800
sawa
  • 165,429
  • 45
  • 277
  • 381
1

There is a shorter solution:

@cleaned = @message_to[/[^@]+/]
Edd Steel
  • 719
  • 4
  • 16
0

The simplest RegEx I got to work in the IRB console is:

@message_to = 'bob@google.com'
@cleaned = @message_to.match(/(.+)@/)[1]

Also from this link you could try:

@cleaned = @message_to.match(/^(?<local_part>[\w\W]*?)@/)[:local_part]
Matt
  • 14,353
  • 5
  • 53
  • 65
0

The most obvious way to adjust your code is by using a forward positive assertion. Instead of saying "match bob@" you're now saying "match bob, when followed by a @"

@message_to = 'bob@google.com'

@cleaned = @message_to.match(/^(.*)+(?=@)/)

A further point about when to use and not to use regexes: yes, using a regex is a bit pointless in this case. But when you do use a regex, it's easier to add validation as well:

@cleaned = @message_to.match(/^(([-a-zA-Z0-9!#$%&'*+\/=?^_`{|}~]+.)*[-a-zA-Z0-9!#$%&'*+\/=?^_`{|}~]+(?=@)/)

(and yes, all those are valid in email-adresses)

markijbema
  • 3,985
  • 20
  • 32
  • "But when you do use a regex, it's easier to add validation as well", except those don't really cover all the corner cases for email addresses, or test whether it's a live address, which is the real-world test. Perl's [Mail::RFC822::Address](http://cpansearch.perl.org/src/PDWARREN/Mail-RFC822-Address-0.3/Address.pm) module has the `make_rfc822re` function which takes a pretty good shot at generating a RFC-compliant [regex](http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html). This is a pertinent discussion: http://stackoverflow.com/q/211842/128421 – the Tin Man Feb 28 '11 at 04:15