Ruby: How do I capture part of a string with regex? - ruby

I have
file_ext = attach.document_file_name.capture(/\.[^.]*$/)
but i guess there is no method capture.
I'm trying to get the file extension from a string. I don't yet have the file.

There is also the built-in ruby function File.extname:
file_ext = File.extname(attach.document_file_name)
(with the difference that File.extname('hello.') returns '', whereas your regex would return '.')

How about:
file_ext = attach.document_file_name[/\.[^.]*$/]

You can do RegEx match in ruby like so:
file_ext = (/\.[^.]*$/.match(attach.document_file_name.to_s)).to_s
Fore more information please check http://ruby-doc.org/core/classes/Regexp.html

If you want to use an regexp to do this, you can simply do:
irb(main):040:0> "foo.txt"[/\w*.(\w*)/,1]
=> "txt"

Related

Ruby : find/scan/search a string in a sentence in

I am trying to find a string in a sentence
/a.**117228558440230**.24692.116944575135295/65456
want the string after a and before first . in ruby on rails
thanks in advance
One way is to find the "a." then capture everything until the next "." like this:
result = sentence =~ /a\.(.*?)\./ && $1
You can do that with a simple regexp:
string = '/a.117228558440230.24692.116944575135295/65456'
regexp = /\D\.(\d*)\./
regexp.match(string)[1]
#=> "117228558440230"
You can also give a try to this
str = "/a.**117228558440230**.24692.116944575135295/65456"
str[/\D\.(\d*)\./]
=> "*.24692."
This methods gives you the string if available in the sentence otherwise nil

Ruby: Get filename without the extensions

How can I get the filename without the extensions? For example, input of "/dir1/dir2/test.html.erb" should return "test".
In actual code I will passing in __FILE__ instead of "/dir1/dir2/test.html.erb".
Read documentation:
basename(file_name [, suffix] ) → base_name
Returns the last component of the filename given in file_name, which
can be formed using both File::SEPARATOR and File::ALT_SEPARATOR as
the separator when File::ALT_SEPARATOR is not nil. If suffix is given
and present at the end of file_name, it is removed.
=> File.basename('public/500.html', '.html')
=> "500"
in you case:
=> File.basename("test.html.erb", ".html.erb")
=> "test"
How about this
File.basename(f, File.extname(f))
returns the file name without the extension.. works for filenames with multiple '.' in it.
In case you don't know the extension you can combine File.basename with File.extname:
filepath = "dir/dir/filename.extension"
File.basename(filepath, File.extname(filepath)) #=> "filename"
Pathname provides a convenient object-oriented interface for dealing with file names.
One method lets you replace the existing extension with a new one, and that method accepts the empty string as an argument:
>> Pathname('foo.bar').sub_ext ''
=> #<Pathname:foo>
>> Pathname('foo.bar.baz').sub_ext ''
=> #<Pathname:foo.bar>
>> Pathname('foo').sub_ext ''
=> #<Pathname:foo>
This is a convenient way to get the filename stripped of its extension, if there is one.
But if you want to get rid of all extensions, you can use a regex:
>> "foo.bar.baz".sub(/(?<=.)\..*/, '')
=> "foo"
Note that this only works on bare filenames, not paths like foo.bar/pepe.baz. For that, you might as well use a function:
def without_extensions(path)
p = Pathname(path)
p.parent / p.basename.sub(
/
(?<=.) # look-behind: ensure some character, e.g., for ‘.foo’
\. # literal ‘.’
.* # extensions
/x, '')
end
Split by dot and the first part is what you want.
filename = 'test.html.erb'
result = filename.split('.')[0]
Considering the premise, the most appropriate answer for this case (and similar cases with other extensions) would be something such as this:
__FILE__.split('.')[0...-1].join('.')
Which will only remove the extension (not the other parts of the name: myfile.html.erb here becomes myfile.html, rather than just myfile.
Thanks to #xdazz and #Monk_Code for their ideas. In case others are looking, the final code I'm using is:
File.basename(__FILE__, ".*").split('.')[0]
This generically allows you to remove the full path in the front and the extensions in the back of the file, giving only the name of the file without any dots or slashes.
name = "filename.100.jpg"
puts "#{name.split('.')[-1]}"
Yet understanding it's not a multiplatform solution, it'd work for unixes:
def without_extensions(path)
lastSlash = path.rindex('/')
if lastSlash.nil?
theFile = path
else
theFile = path[lastSlash+1..-1]
end
# not an easy thing to define
# what an extension is
theFile[0...theFile.index('.')]
end
puts without_extensions("test.html.erb")
puts without_extensions("/test.html.erb")
puts without_extensions("a.b/test.html.erb")
puts without_extensions("/a.b/test.html.erb")
puts without_extensions("c.d/a.b/test.html.erb")

Using regexes in Ruby

I have a regex, that I'm trying to use in Ruby. Here is my Regex, and it works in Java when I add the double escape keys
\(\*(.*?)\*\)
I know this is a simple question, but how would I write this as a ruby expression and set it equal to a variable? I appreciate any help.
try this:
myregex = /\(\*(.*?)\*\)/
To be clear, this is just to save the regex to a variable. To use it:
"(**)" =~ myregex
Regular expressions are a native type in Ruby (the actual class is "Pattern"). You can just write:
mypat = /\(\*(.*?)\*\)/
[Looks like anything between '(' / ')' pairs, yes?]
You can then do
m = mypat.match(str)
comment = m[1]
...or, more compactly
comment = mypat.match(str)[1]
try this:
if /\(\*(.*?)\*\)/ === "(*hello*)"
content = $1 # => "hello"
end
http://rubular.com/r/7eCuPX3ri0

Ruby Regular Expression Excluding

#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
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"
>>
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]
There is a shorter solution:
#cleaned = #message_to[/[^#]+/]
An even shorter code than mu_is_too_short would be:
#cleaned = #message_to[/^([^#]+)#/, 1]
The String#[] method can take a regular expression.
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]
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)

how to do the following in ruby?

I need to grab a string like
"/html/body/a"
i need to check the last portion, in this case "a" after the final "/"
how can i do this ? how can i regex match for the last item after the final "/" ?
x = "/html/body/a"
x.split("/").last # => "a"
Regex? Not sure, but what's wrong with
my_string.split("/").last # Maybe you want some error checking here, I don't know.
If you want to use regexp, this would be it:
mystring = "/html/body/a"
if mystring =~ /([^\/]+)$/
last_part = $1
end

Resources