Extract Date from string ruby - ruby

I have this string :
Rep. Barletta, Lou [R-PA-11] (Introduced 06/04/2015)
And I want to extract the date which is "06/04/2015". How do i do this in ruby?
I have tried to do something like this:
str[-1..-11]
but didnt work. Any suggestion? Thanks!

str = "Rep. Barletta, Lou [R-PA-11] (Introduced 06/04/2015)"
str.match(/(\d{2}\/\d{2}\/\d{4})/)[0]
#=> "06/04/2015"
This code matches anything that's in the format of 2 numbers/2 numbers/4 numbers and returns it.
If there's a possibility of having XX/XX/XXXX somewhere else in the string, I'd probably use the following code instead:
str = "Rep. Barletta, Lou [R-PA-11] (Introduced 06/04/2015)"
str.match(\(Introduced (\d{2}\/\d{2}\/\d{4})\)$)[0]
#=> "06/04/2015"
This searches for (Introduced XX/XX/XXXX) and grabs the date from that in particular.

Date has a parse method, which happens to just work.
require 'date'
str = "Rep. Barletta, Lou [R-PA-11] (Introduced 06/04/2015)"
p d = Date.parse(str) # => #<Date: 2015-04-06 ((2457119j,0s,0n),+0s,2299161j)>

str[-11..-2] if the position of the date does not change

I agree with Piccolo's comment. Here is a simple regular expression you can try in irb. I recommend experimenting in irb to learn some rudimentary Ruby regular expressions.
For example, /.+([0-9]{2}\/[0-9]{2}\/[0-9]{4}).+/ looks for anything followed by two digits, slash, two digits, slash, four digits, then anything:
$ irb
2.2.0 :001 > s='Rep. Barletta, Lou [R-PA-11] (Introduced 06/04/2015)'
2.2.0 :009 > /.+([0-9]{2}\/[0-9]{2}\/[0-9]{4}).+/ =~ s && $1
=> "06/04/2015"
2.2.0 :010 >

#steenslag's answer looks for valid dates (unlike the other answers), but could still be tripped up:
str = "The first 10 may go 15/15/2015 with Lou (Introduced 06/04/2015)"
Date.parse(str)
#=> #<Date: 2015-05-10 ((2457153j,0s,0n),+0s,2299161j)>
To ensure the date is in the specified format, you could do the following:
require 'date'
def extract_date(str, fmt)
a = str.each_char
.each_cons(10)
.find { |a| Date.strptime(a.join, fmt) rescue nil }
a ? a.join : nil
end
For str as above:
extract_date(str, '%d/%m/%Y')
#=> "06/04/2015"
A second example:
extract_date("15/15/2015", '%d/%m/%Y')
#=> nil

Related

Get last character in string

I want to get the last character in a string MY WAY - 1) Get last index 2) Get character at last index, as a STRING. After that I will compare the string with another, but I won't include that part of code here. I tried the code below and I get a strange number instead. I am using ruby 1.8.7.
Why is this happening and how do I do it ?
line = "abc;"
last_index = line.length-1
puts "last index = #{last_index}"
last_char = line[last_index]
puts last_char
Output-
last index = 3
59
Ruby docs told me that array slicing works this way -
a = "hello there"
a[1] #=> "e"
But, in my code it does not.
UPDATE:
I keep getting constant up votes on this, hence the edit. Using [-1, 1] is correct, however a better looking solution would be using just [-1]. Check Oleg Pischicov's answer.
line[-1]
# => "c"
Original Answer
In ruby you can use [-1, 1] to get last char of a string. Here:
line = "abc;"
# => "abc;"
line[-1, 1]
# => ";"
teststr = "some text"
# => "some text"
teststr[-1, 1]
# => "t"
Explanation:
Strings can take a negative index, which count backwards from the end
of the String, and an length of how many characters you want (one in
this example).
Using String#slice as in OP's example: (will work only on ruby 1.9 onwards as explained in Yu Hau's answer)
line.slice(line.length - 1)
# => ";"
teststr.slice(teststr.length - 1)
# => "t"
Let's go nuts!!!
teststr.split('').last
# => "t"
teststr.split(//)[-1]
# => "t"
teststr.chars.last
# => "t"
teststr.scan(/.$/)[0]
# => "t"
teststr[/.$/]
# => "t"
teststr[teststr.length-1]
# => "t"
Just use "-1" index:
a = "hello there"
a[-1] #=> "e"
It's the simplest solution.
If you are using Rails, then apply the method #last to your string, like this:
"abc".last
# => c
You can use a[-1, 1] to get the last character.
You get unexpected result because the return value of String#[] changed. You are using Ruby 1.8.7 while referring the the document of Ruby 2.0
Prior to Ruby 1.9, it returns an integer character code. Since Ruby 1.9, it returns the character itself.
String#[] in Ruby 1.8.7:
str[fixnum] => fixnum or nil
String#[] in Ruby 2.0:
str[index] → new_str or nil
In ruby you can use something like this:
ending = str[-n..-1] || str
this return last n characters
Using Rails library, I would call the method #last as the string is an array. Mostly because it's more verbose..
To get the last character.
"hello there".last() #=> "e"
To get the last 3 characters you can pass a number to #last.
"hello there".last(3) #=> "ere"
Slice() method will do for you.
For Ex
"hello".slice(-1)
# => "o"
Thanks
Your code kinda works, the 'strange number' you are seeing is ; ASCII code. Every characters has a corresponding ascii code ( https://www.asciitable.com/). You can use for conversationputs last_char.chr, it should output ;.

Replacing a %20 with a space in Ruby

I've currently got a string that reads something like ["green%20books"] and I'd like it to read ["green books"].
I thought Googling for this would yield a result pretty quickly but everyone just wants to turn spaces into %20s. Not the other way around.
Any help would be much appreciated!
Edit:
This is the function I'm working with and I'm confused where in here to decode the URL. I tried removing the URI.encode text but that broke the function.
def self.get_search_terms(search_url)
hash = CGI.parse(URI.parse(URI.encode(search_url)).query) #returns a hash
keywords = []
hash.each do |key, value|
if key == "q" || key == "p"
keywords << value
end
end
keywords
end
you can use the 'unencode' method of URI. (aliased as decode)
require 'uri'
URI.decode("green%20books")
# => "green books"
this will not only replaces "%20" with space, but every uri-encoded charcter, which I assume is what you want.
documentation
CGI::unescape will do what you want:
1.9.2-p320 :001 > require 'cgi'
=> true
1.9.2-p320 :002 > s = "green%20books"
=> "green%20books"
1.9.2-p320 :003 > CGI.unescape(s)
=> "green books"
Another option (as YenTheFirst mentioned) might be URI.decode. However, I read a discussion that it would be deprecated -- although that was in 2010.
Anyway, since you're asking about arrays, you would perhaps map using that method:
ary.map { |s| CGI.unescape(s) }
You can use regular expressions:
string = "green%20books"
string.gsub!('%20', ' ')
puts string

How to print a string with a backward slash in Ruby

I have a string str = "xyz\123" and I want to print it as is.
The IRB is giving me an unexpected output. Please find the same below:-
1.9.2p290 :003 > str = "xyz\123"
=> "xyzS"
1.9.2p290 :004 >
Any ideas on how can I get IRB to print the original string i.e. "xyz\123".
Thank you..
UPDATE :
I tried escaping it , but it doesn't seem to be that simple for some reason. Please find below my trials with the same:
1.9.2p290 :004 > str = "xyz'\'123"
=> "xyz''123"
1.9.2p290 :005 > str = "xyz'\\'123"
=> "xyz'\\'123"
1.9.2p290 :006 > str = "xyz'\\\'123"
=> "xyz'\\'123"
1.9.2p290 :007 >
UPDATED answer:
escape token '\' is always working in plain ruby code, but not always working in "ruby console". so I suggest you write a unit test:
# escape_token_test.rb
require 'test/unit'
class EscapeTokenTest < Test::Unit::TestCase
def test_how_to_escape
hi = "hi\\backslash"
puts hi
end
end
and you will get result as:
hi\backslash
and see #pst's comment.
The backslash character is an escape character. You may have seen "\n" be used to display a new line, and that is why. "\123" evaulates the ASCII code for 83, which is "S". To print a backslash use 2 backslashes. So you could use str = "xyz\\123".
How to print a backslash?
Use 2 backslashes, e.g. "xyz\\123"
Why does "xyz\123" evaluate to "xyzS"?
In a double-quoted string, \nnn is an octal escape.
Thomas, D. (2009) Programming Ruby, p.329
So, octal 123
= (64 * 1) + (8 * 2) + 3
= decimal 83
= ASCII S
It's simple ... try dump function:
mystring = %Q{"Double Quotes"}
p mystring.dump
=> "\"\\\"Double Quotes\\\"\""
p mystring
=>"\"Double Quotes\""

How do I remove a substring after a certain character in a string using Ruby?

How do I remove a substring after a certain character in a string using Ruby?
new_str = str.slice(0..(str.index('blah')))
I find that "Part1?Part2".split('?')[0] is easier to read.
I'm surprised nobody suggested to use 'gsub'
irb> "truncate".gsub(/a.*/, 'a')
=> "trunca"
The bang version of gsub can be used to modify the string.
str = "Hello World"
stopchar = 'W'
str.sub /#{stopchar}.+/, stopchar
#=> "Hello W"
A special case is if you have multiple occurrences of the same character and you want to delete from the last occurrence to the end (not the first one).
Following what Jacob suggested, you just have to use rindex instead of index as rindex gets the index of the character in the string but starting from the end.
Something like this:
str = '/path/to/some_file'
puts str.slice(0, str.index('/')) # => ""
puts str.slice(0, str.rindex('/')) # => "/path/to"
We can also use partition and rpartitiondepending on whether we want to use the first or last instance of the specified character:
string = "abc-123-xyz"
last_char = "-"
string.partition(last_char)[0..1].join #=> "abc-"
string.rpartition(last_char)[0..1].join #=> "abc-123-"

Ruby: How to get the first character of a string

How can I get the first character in a string using Ruby?
Ultimately what I'm doing is taking someone's last name and just creating an initial out of it.
So if the string was "Smith" I just want "S".
You can use Ruby's open classes to make your code much more readable. For instance, this:
class String
def initial
self[0,1]
end
end
will allow you to use the initial method on any string. So if you have the following variables:
last_name = "Smith"
first_name = "John"
Then you can get the initials very cleanly and readably:
puts first_name.initial # prints J
puts last_name.initial # prints S
The other method mentioned here doesn't work on Ruby 1.8 (not that you should be using 1.8 anymore anyway!--but when this answer was posted it was still quite common):
puts 'Smith'[0] # prints 83
Of course, if you're not doing it on a regular basis, then defining the method might be overkill, and you could just do it directly:
puts last_name[0,1]
If you use a recent version of Ruby (1.9.0 or later), the following should work:
'Smith'[0] # => 'S'
If you use either 1.9.0+ or 1.8.7, the following should work:
'Smith'.chars.first # => 'S'
If you use a version older than 1.8.7, this should work:
'Smith'.split(//).first # => 'S'
Note that 'Smith'[0,1] does not work on 1.8, it will not give you the first character, it will only give you the first byte.
"Smith"[0..0]
works in both ruby 1.8 and ruby 1.9.
For completeness sake, since Ruby 1.9 String#chr returns the first character of a string. Its still available in 2.0 and 2.1.
"Smith".chr #=> "S"
http://ruby-doc.org/core-1.9.3/String.html#method-i-chr
In MRI 1.8.7 or greater:
'foobarbaz'.each_char.first
Try this:
>> a = "Smith"
>> a[0]
=> "S"
OR
>> "Smith".chr
#=> "S"
In Rails
name = 'Smith'
name.first
>> s = 'Smith'
=> "Smith"
>> s[0]
=> "S"
Another option that hasn't been mentioned yet:
> "Smith".slice(0)
#=> "S"
Because of an annoying design choice in Ruby before 1.9 — some_string[0] returns the character code of the first character — the most portable way to write this is some_string[0,1], which tells it to get a substring at index 0 that's 1 character long.
Try this:
def word(string, num)
string = 'Smith'
string[0..(num-1)]
end
If you're using Rails You can also use truncate
> 'Smith'.truncate(1, omission: '')
#=> "S"
or for additional formatting:
> 'Smith'.truncate(4)
#=> "S..."
> 'Smith'.truncate(2, omission: '.')
#=> "S."
While this is definitely overkill for the original question, for a pure ruby solution, here is how truncate is implemented in rails
# File activesupport/lib/active_support/core_ext/string/filters.rb, line 66
def truncate(truncate_at, options = {})
return dup unless length > truncate_at
omission = options[:omission] || "..."
length_with_room_for_omission = truncate_at - omission.length
stop = if options[:separator]
rindex(options[:separator], length_with_room_for_omission) || length_with_room_for_omission
else
length_with_room_for_omission
end
"#{self[0, stop]}#{omission}"
end
Other way around would be using the chars for a string:
def abbrev_name
first_name.chars.first.capitalize + '.' + ' ' + last_name
end
Any of these methods will work:
name = 'Smith'
puts name.[0..0] # => S
puts name.[0] # => S
puts name.[0,1] # => S
puts name.[0].chr # => S

Resources