Rails: truncate string after match - ruby-on-rails

Say I've got a string like so:
"This belongs to that then there's this other keyword which does something else."
How would I truncate it so it'd find keyword and truncate keyword which does something else. to give me only:
"This belongs to that then there's this other "
Thanks!

1.9.3p327 > str = "This belongs to that then there's this other keyword which does something else."
=> "This belongs to that then there's this other keyword which does something else."
1.9.3p327 > str.sub(/keyword.*/, '')
=> "This belongs to that then there's this other "
Be careful though as this will also match on "keywordwithnotrailingspace". Look into \b for getting word boundaries...

A simple tool to add to your toolbelt is Rubular. You can test all sorts of awesome Regex right within your browser... Teach a man to fish ... you know the saying. :)
#emm - I think #Philip's answer is correct; however, I would use a combination of both answers and go with keyword[.|\s]*

Related

Replace of forward slash to backslash in ruby from any path

After a lot of research and brainstorm finally i give up for it and need a help to convert the forwardslash to single backslash But I am not able to do.
Here is some steps which i followed but it does n't works
"C:/projects/test/code".gsub('/','\\') => "C:\\projects\\test\\code"
"C:/projects/test/code".gsub('/','\\\\') => "C:\\projects\\test\\code"
"C:/projects/test/code".gsub('/',"\'\\'") => "C:'projects/test/codeprojects'test/codetest'codecode"
The result which i expect to be should like:
=> "C:\projects\test\code"
Any help and suggestions accepted please help
You did it already with this:
"C:/projects/test/code".gsub('\', '\\') # => "C:\\projects\\test\\code"
Likely you are confused by \\ in output. It's normal. Just try to puts this:
puts "C:/projects/test/code".gsub(/\//, '\\') # => C:\projects\test\code
Updated:
\ is used in Ruby (and not only) for multiline string concatenation so when you just type it in irb, for example, it continues reading user's input.
Some notes about irb:
when you execute some command in irb it outputs the result for debugging purposes:
irb> "foo\r\nbar"
=> "foo\r\nba"
This line contains \r\n what means go to the beginning of the new new line. So if you want to see it in human mode just print it and it gives:
irb> puts "foo\r\nbar"
foo
bar
If you want to prevent output you can use semicolon:
irb> s = "foo\r\nbar";
irb* puts s
foo
bar
What you get in your first example is exactly what you need. In IRB/Pry the representation differs, because REPL is intended to support copy-paste, and the string you see is the exact string with single backward slashes, how one would type it inside double quotes. You might also note double quotes around the string in the REPL representation, which do not belong to the string itself either.
Here is another more explicit way to accomplish a task:
result = "C:/projects/test/code".split('/').join('\\')
#⇒ "C:\\projects\\test\\code"
See:
puts result
#⇒ C:\projects\test\code
result.count("\\")
#⇒ 3
As a matter of fact, Windows does indeed understand the path with forward slashes, so you probably don’t need this conversion at all.

How can I match a partial string to a database's object's attribute? Regexp?

I have a database containing a list of movies. A typical entry look like this:
id: 1,
title: "Manhatten and the Murderer",
year: 1928,
synopsis: 'some text...'
rating: 67,
genre_id, etc. etc.
Now I'm trying to make a series of search tests pass and so far I have made a single test case pass where if you type the title "Manhatten and the Murderer" in a text field it will find the movie that you want. The problem is with partial matching.
Now I'd like a way to search "Manhat" and match the record "Manhatten and the Murderer". I also want it to match with any movie that has "Manhat" in it. For example, it would return maybe 2 or 3 others like title: "My life in Manhattan", title: "The Big Apple in Manhattan" etc. etc.
Below is the code that I have so far in my Movie model:
def self.search(query)
# Replace this with the appropriate ActiveRecord calls...
if query =~ where(title:)
#where(title: query)
binding.pry
end
end
My question is, how can I set this up? My problem is the "where(title:) line. One thought was to use Regexp to match the title attribute. Any help would be appreciated! Thanks.
Use a query that searches a substring in between:
name = "Manhattan"
Movie.where("title like ?", "%#{name}%")
For example:
%Manhattan will get you: Love in Manhattan
Manhattan% will get: Manhattan and Company
%Manhattan% will get you both: [Love in Manhattan, Manhattan and Company]
But, if you're searching through movies synopsis, you should use Thinking Sphinx or Elastic Search
For example, with Elastic Search, you could set the synopsis like this:
Add app/indices/movie_index.rb:
ThinkingSphinx::Index.define :movie, :with => :active_record do
# fields
indexes title, :sortable => true
indexes synopsis
end
Index your data with rake ts:index
And then run Sphynx with: rake ts:start
You can search just like this:
Movie.search :conditions => {:synopsis => "Manhattan"}
Elastic Search is a great alternative to ThinkingSphinx, there's even a RailsCast about it, so you should definitely take a look to see what really suites you best... Hope this helps!
You do not need regex to find movies that have the search string. You can use SQL query like this:
Movie.where('title LIKE ?','Batman%')
That would return all movies start with "Batman"
Movie.where('title LIKE ?','%Batman%')
That would return all movies that have Batman anywhere in it's title.
I think you figured out the '%' is a joker character in the query.
One option is to run a search server alongside your Rails application. It is certainly my go to solution. This route offers a ton of features not found within Rails itself and might be overkill, but worth consideration.
I use Sphinx and implement it using the thinking-sphinx gem.
Resources:
http://pat.github.io/thinking-sphinx/
http://sphinxsearch.com/

How to modify user input?

I wrote an little demo code, to show you my problem:
puts "Enter your feeling"
a = gets.chomp
#feel = "good"
puts a
SO when it comes to the input, i type in:
Actually i fell very #{#feel}
Then i hope to get this output:
Actually i fell very good
But instead i get this output:
Actually i fell very #{#feel}
What did i make wrong?
It honestly isn't too safe to interpolate arbitrary strings from the user. Basically it's the same as using Kernel#eval (which will work in your case) ... the user can put whatever they want and it is extremely easy to abuse and compromise your system. You could technically do a little by simply filtering out quotation marks in what they type, but honestly it's a bad choice.
What you can do is do a string replace for #{#feel} with #feel, if #feel is the only thing you are going to allow them to interpolate:
puts a.gsub('#{#feel}',#feel)
"#{#feel}"
may be this what you need I feel.
and try to follow naming conventions.
instead of
puts a
it should be
puts "Actually i feel very " + #feel
Simple answer is you can't.
Interpolation happens at run time, so even if you could get this to work, #feel would be nil at the time you input it.
You would be better doing something like:
puts "Enter your feeling"
a = gets.chomp
#feel = "good"
puts a.gsub("##feel##",#feel)
Then asked how you feel enter:
Actually I feel very ##feel##

Capitalization API

Is there any good API or service that handles capitalization well? It should be able to handle input like "i need help fixing my iphone asap" with a desired output of "I Need Help Fixing My iPhone ASAP".
Edit: This is in conjunction with titleize. Titleize doesn't handle words like "iPhone" and acronyms. I'm currently getting user input like "ceo" and titleize returns "Ceo", when I'd like "CEO". I'd prefer not to write a list of special capitalizations, especially if there is a good alternative.
Another alternative would be a library of words and the correct capitalization.
Have a look at #titleize in ActiveSupport::Inflector
"man from the boondocks".titleize # => "Man From The Boondocks"
"x-men: the last stand".titleize # => "X Men: The Last Stand"
"TheManWithoutAPast".titleize # => "The Man Without A Past"
"raiders_of_the_lost_ark".titleize # => "Raiders Of The Lost Ark"
Cut and paste from http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-titleize

Stripping the first character of a string

i have
string = "$575.00 "
string.to_f
// => 0.0
string = "575.00 "
string.to_f
// => 575.0
the value coming in is in this format and i need to insert into a database field that is decimal any suggestions
"$575.00 "
We did this so often we wrote an extension to String called cost_to_f:
class String
def cost_to_f
self.delete('$,').to_f
end
end
We store such extensions in config/initializers/extensions/string.rb.
You can then simply call:
"$5,425.55".cost_to_f #=> 5425.55
If you are using this method rarely, the best bet is to simply create a function, since adding functions to core classes is not exactly something I would recommend lightly:
def cost_to_f(string)
string.delete('$,').to_f
end
If you need it in more than one class, you can always put it in a module, then include that module wherever you need it.
One more tidbit. You mentioned that you need to process this string when it is being written to the database. With ActiveRecord, the best way to do this is:
class Item < ActiveRecord::Base
def price=(p)
p = p.cost_to_f if p.is_a?(String)
write_attribute(:price, p)
end
end
EDIT: Updated to use String#delete!
So many answers... i'll try to summarize all that are available now, before give own answer.
1. string.gsub(/[\$,]/, '')
string.gsub!(/^\$/, '')
2. string[1..-1]
3. string.slice(0) # => "ome string"
4. s/^.//
Why (g)sub and regexp Just for deleting a character? String#tr is faster and shorter. String#delete is even better.
Good, fast, simple. Power of reverse indexing.
Hm... looks like it returns "S". Because it is an alias to String#[]
Perl? /me is cheking question tags...
And my advice is:
What if you have not dollar, but yena? Or what if you don't even have anything before numbers?
So i'll prefer:
string[/\d.+/]
This will crop leading non-decimal symbols, that prevent to_f to work well.
P.S.: By the way. It's known, that float is bad practice for storing money amounts.
Use Float or Decimal for Accounting Application Dollar Amount?
You could try something like this.
string = string[1..-1] if string.match(/^\$/)
Or this.
string.gsub!(/^\$/, '')
Remember to put that backslash in your Regexp, it also means "end of string."
you can use regex for that:
s/^.//
As laways, this is PCRE syntax.
In Ruby, you can use the sub() method of the string class to replace the string:
result = string.sub(/^./,"")
This should work.
[EDIT]
Ok, someone asked what's the gsub() is for:
gsub() acts like sub() but with the /g modifier in PCRE (for global replacement):
s/a/b/
in PCRE is
string.sub(/a/, "b")
and
s/a/b/g
is
string.gsub(/a/, "b")
in Ruby
What I'd use (instead of regular expressions) is simply the built-in slice! method in the String class. For example,
s = "Some string"
s.slice!(0) # Deletes and returns the 0th character from the string.
s # => "ome string"
Documentation here.

Resources