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
Related
I have a string as given below,
./component/unit
and need to split to get result as component/unit which I will use this as key for inserting hash.
I tried with .split(/.\//).last but its giving result as unit only not getting component/unit.
I think, this should help you:
string = './component/unit'
string.split('./')
#=> ["", "component/unit"]
string.split('./').last
#=> "component/unit"
Your regex was almost fine :
split(/\.\//)
You need to escape both . (any character) and / (regex delimiter).
As an alternative, you could just remove the first './' substring :
'./component/unit'.sub('./','')
#=> "component/unit"
All the other answers are fine, but I think you are not really dealing with a String here but with a URI or Pathname, so I would advise you to use these classes if you can. If so, please adjust the title, as it is not about do-it-yourself-regexes, but about proper use of the available libraries.
Link to the ruby doc:
https://docs.ruby-lang.org/en/2.1.0/URI.html
and
https://ruby-doc.org/stdlib-2.1.0/libdoc/pathname/rdoc/Pathname.html
An example with Pathname is:
require 'pathname'
pathname = Pathname.new('./component/unit')
puts pathname.cleanpath # => "component/unit"
# pathname.to_s # => "component/unit"
Whether this is a good idea (and/or using URI would be cool too) also depends on what your real problem is, i.e. what you want to do with the extracted String. As stated, I doubt a bit that you are really intested in Strings.
Using a positive lookbehind, you could do use regex:
reg = /(?<=\.\/)[\w+\/]+\w+\z/
Demo
str = './component'
str2 = './component/unit'
str3 = './component/unit/ruby'
str4 = './component/unit/ruby/regex'
[str, str2, str3, str4].each { |s| puts s[reg] }
#component
#component/unit
#component/unit/ruby
#component/unit/ruby/regex
I am trying to see if the string s contains any of the symbols in a regex. The regex below works fine on rubular.
s = "asd#d"
s =~ /[~!##$%^&*()]+/
But in Ruby 1.9.2, it gives this error message:
syntax error, unexpected ']', expecting tCOLON2 or '[' or '.'
s = "asd#d"; s =~ /[~!##$%^&*()]/
What is wrong?
This is actually a special case of string interpolation with global and instance variables that most seem not to know about. Since string interpolation also occurs within regex in Ruby, I'll illustrate below with strings (since they provide for an easier example):
#foo = "instancefoo"
$foo = "globalfoo"
"##foo" # => "instancefoo"
"#$foo" # => "globalfoo"
Thus you need to escape the # to prevent it from being interpolated:
/[~!#\#$%^&*()]+/
The only way that I know of to create a non-interpolated regex in Ruby is from a string (note single quotes):
Regexp.new('[~!##$%^&*()]+')
I was able to replicate this behavior in 1.9.3p0. Apparently there is a problem with the '#$' combination. If you escape either it works. If you reverse them it works:
s =~ /[~!#$#%^&*()]+/
Edit: in Ruby 1.9 #$ invokes variable interpolation, even when followed by a % which is not a valid variable name.
I disagree, you need to escape the $, its the end of string character.
s =~ /[~!##\$%^&*()]/ => 3
That is correct.
#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)
I have special strings like name1="value1" name2='value2'. Values can contain whitespaces and are delimited by either single quotes or double quotes. Names never contain whitespaces. name/value pairs are separated by whitespaces.
I want to parse them into a list of name-value pairs like this
string.magic_split() => { "name1"=>"value1", "name2"=>"value2" }
If Ruby understood lookaround assertions, I could do this by
string.split(/[\'\"](?=\s)/).each do |element|
element =~ /(\w+)=[\'\"](.*)[\'\"]/
hash[$1] = $2
end
but Ruby does not understand lookaround assertions, so I am somewhat stuck.
However, I am sure that there are much more elegant ways to solve this problem anyway, so I turn to you. Do you have a good idea for solving this problem?
This fails on values like '"hi" she said', but it might be good enough.
str = %q(name1="value1" name2='value 2')
p Hash[ *str.chop.split( /' |" |='|="/ ) ]
#=> {"name1"=>"value1", "name2"=>"value 2"}
This is not a complete answer, but Oniguruma, the standard regexp library in 1.9 supports lookaround assertions. It can be installed as a gem if you are using Ruby 1.8.x.
That said, and as Sorpigal has commented, instead of using a regexp I would be inclined to iterate through the string one character at a time keeping track of whether you are in a name portion, when you reach the equals sign, when you are within quotes and when you reach a matched closing quote. On reaching a closing quote you can put the name and value into the hash and proceed to the next entry.
class String
def magic_split
str = self.gsub('"', '\'').gsub('\' ', '\'\, ').split('\, ').map{ |str| str.gsub("'", "").split("=") }
Hash[str]
end
end
This should do it for you.
class SpecialString
def self.parse(string)
string.split.map{|s| s.split("=") }.inject({}) {|h, a| h[a[0]] = a[1].gsub(/"|'/, ""); h }
end
end
Have a try with : /[='"] ?/
I don't know Ruby syntax but here is a Perl script you could translate
#!/usr/bin/perl
use 5.10.1;
use warnings;
use strict;
use Data::Dumper;
my $str = qq/name1="val ue1" name2='va lue2'/;
my #list = split/[='"] ?/,$str;
my %hash;
for (my $i=0; $i<#list;$i+=3) {
$hash{$list[$i]} = $list[$i+2];
}
say Dumper \%hash;
Output :
$VAR1 = {
'name2' => 'va lue2',
'name1' => 'val ue1'
};
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"