hken27
hken27

Reputation: 413

Ruby expression to return first x letters and also first word

I want to use regex to solve this. I am open to other short efficient ideas.

Using any methods and whatever else:

split()
scan()
match()

Q#1 I want to return the number of letters in a word

def first_letters(str, num)
  str.scan(/...???/
end

first_letters ("hello", 1) ==> returns "h"
first_letters ("hello", 3) ==> returns "hel"
first_letters ("John", 2) ==> returns "Jo"

Q#2 Return first word

def first_word(str)       
   str.scan(/?...?/
end

   first_word("hello world")  ==> return "hello"
   first_word("Hey You")  ==> return "Hey"

Upvotes: 0

Views: 1034

Answers (3)

the Tin Man
the Tin Man

Reputation: 160581

While it's admirable that you want to learn regex, your constraints are hardly good use-cases for regular expressions, and instead are pretty badly contrived.

You can retrieve the first n letters using a pattern and one of these:

str = 'foobar'
str.scan(Regexp.new("^.{3}")).first # => "foo"
str.split(//)[0, 3].join # => "foo"
str.match(/^(.{3})/)[1] # => "foo"

But, why, when it's more direct and simple to slice the string?

str[0, 3] # => "foo"

You can retrieve the first word using a pattern and one of these:

str = 'foo bar'
str.scan(Regexp.new("\S+")).first # => nil
str.scan(Regexp.new("\w+")).first # => nil
str.split(/ /)[0] # => "foo"
str.match(/^([a-z]+)/i)[1] # => "foo"

Or do it directly:

str.split[0] # => "foo"
str.split.first # => "foo"

(split uses regex internally to break "foo bar" into two words by finding "white-space" but it hides that from us, so technically it's using them but we don't really see it.)

Knowing why and when you should use a regular expression is very important. They're great when you want to retrieve reoccurring patterns of data from text, like numbers intermingled inside text, things that look like IP numbers, or to tear apart HTTP server log files (which sometimes is better done using string slices).

Upvotes: 1

Michael Durrant
Michael Durrant

Reputation: 96544

Returning 'n' numbr of letters, or word 'n' isn't something you do with a regex.

def first_letters(str, num)
  str[0,num]
end

2.0.0-p247 :023 > first_letters("hello", 1)  
 => "h" 
2.0.0-p247 :024 > first_letters("hello", 3)  
 => "hel" 
2.0.0-p247 :025 > first_letters("John", 2)  
 => "Jo" 

and

def first_word(str)       
   str.split[0]
end

2.0.0-p247 :033 > first_word("hello world")                                     
 => "hello" 
2.0.0-p247 :034 > first_word("Hey You")
 => "Hey" 

A regex is used when you want to match based on a pattern.

For instance, say you want to match any lines that START with possibly spaces, the word browser, a 'dot' and that end with )}

for that you would use this: /^[[:space]]*browser\..*\)\}/ As you can see it's matching using a pattern, so it would select lines such as:

browsers {( all )}
  browser with more words here {( all )}
     browser even when missing brackets here all )}

but it would NOT match and select lines such as these:

browsers {( all )
  rowsers with more words {( all )}
     browsers  ([])

So as a method it would be

def first_word(str)       
  str.match(/^[[:space]]*browser\..*\)\}/)    
end

Upvotes: 1

falsetru
falsetru

Reputation: 369314

You don't need to use regular expression.

def first_letters(str, num)
  str[0, num]
end


def first_word(str)       
   str.split[0]
end

Using regular expression:

def first_letters(str, num)
  str[Regexp.new("^.{#{num}}")]
end

def first_word(str)       
   str[/\w+/] # or str[/\S+/]
end

Upvotes: 4

Related Questions