0
@message_to = '[email protected]'

@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

3
  • 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? Commented Feb 28, 2011 at 4: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. Commented Mar 1, 2011 at 6:57
  • @mu is too short, LOL. Yes, very possibly. I always thought it was a macho thing. Commented Mar 1, 2011 at 23:13

6 Answers 6

5

No need much regular expression

>> @message_to = "[email protected]"
=> "[email protected]"
>> @message_to.split("@",2)
=> ["bob", "google.com"]
>> @message_to.split("@",2)[0] if @message_to["@"]
=> "bob"
>>
Sign up to request clarification or add additional context in comments.

2 Comments

+1: People do tend to get fixated on using regexes for everything, basic string mangling shouldn't be overlooked.
+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.
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]

Comments

1

There is a shorter solution:

@cleaned = @message_to[/[^@]+/]

Comments

1

An even shorter code than mu_is_too_short would be:

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

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

Comments

0

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

@message_to = '[email protected]'
@cleaned = @message_to.match(/(.+)@/)[1]

Also from this link you could try:

@cleaned = @message_to.match(/^(?<local_part>[\w\W]*?)@/)[:local_part]

Comments

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 = '[email protected]'

@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)

1 Comment

"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 module has the make_rfc822re function which takes a pretty good shot at generating a RFC-compliant regex. This is a pertinent discussion: stackoverflow.com/q/211842/128421

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.