What is the Ruby equivalent of preg_quote()? - ruby

In PHP you need to use preg_quote() to escape all the characters in a string that have a particular meaning in a regular expression, to allow (for example) preg_match() to search for those special characters.
What is the equivalent in Ruby of the following code?
// The content of this variable is obtained from user input, in example.
$search = "$var = 100";
if (preg_match('/' . preg_quote($search, '/') . ";/i")) {
// …
}

You want Regexp.escape.
str = "[...]"
re = /#{Regexp.escape(str)}/
"la[...]la[...]la".gsub(re,"") #=> "lalala"

Related

The letter disapperaed after Splitting string in my ruby program

I am newbie in ruby. In my ruby program, there is a part of code for parsing geocode. The code is like below:
string = "GPS:3;S23.164865;E113.428970;88"
info = string.tr("GPS:",'')
info_array = info.split(";")
puts "GPS: #{info_array[0]},#{info_array[1]},#{info_array[2]}"
The code should split the string into 3 piece: 3, S23.164865 and E113.428970;88 and the expected output is
GPS: 3,S23.164865,E113.428970
but the result is:
GPS: 3,23.164865,E113.428970
Yes, the 'S' letter disappered...
If I use
string = "GPS:3;N23.164865;E113.428970;88"
info = string.tr("GPS:",'')
info_array = info.split(";")
puts "GPS: #{info_array[0]},#{info_array[1]},#{info_array[2]}"
, it prints expected result
GPS: 3,N23.164865,E113.428970
I am very confused why this happens. Can you help?
It looks like you were expecting String#tr to behave like String#gsub.
Calling string.tr("GPS:", '') does not replace the complete string "GPS:" with the empty string. Instead, it replaces any character from within the string "GPS:" with an empty string. Commonly you will find .tr() called with an equal number of input and replacement characters, and in that case the input character is replaced by the output character in the corresponding position. But the way you have called it with only the empty string '' as its translation argument, will delete any of G, P, S, : from anywhere within the string.
>> "String with S and G and a: P".tr("GPS:", '')
=> "tring with and and a "
Instead, use .gsub('GPS:', '') to replace the complete match as a group.
string = "GPS:3;S23.164865;E113.428970;88"
info = string.gsub('GPS:', '')
info_array = info.split(";")
puts "GPS: #{info_array[0]},#{info_array[1]},#{info_array[2]}"
# prints
GPS: 3,S23.164865,E113.428970
Here we've called .gsub() with a string argument. It is probably more often called with a regexp search match argument though.

Extract values after pattern in Ruby string

I have a string like this:
"<root><some ProdCode=\"40\" ProducerName=\"demo1\" ProdCode=\"40\" Need_Confirmation=\"1\"/><some ProdCode=\"40\" ProducerName=\"demo1\" ProdCode=\"40\" Need_Confirmation=\"1\"/></root>"
I'm trying to pull the content from this string which is between =\"content\" and put it in an array, like ["40","demo1","40","1",40......]
You should use :scan to select elements by regexp pattern. Then remove escape characters.
string.scan(/"[^"]+"/).map { |element| element.delete('\\"') }
Explanation of pattern:
/ – regexp starts
" – first char should be "
[^"]+ – next should be any char except ". + sign says that number of such chars should be at least 1.
" – next should be again "
/ – regexp ends
So string.scan(/"[^"]+"/) would return:
["\"40\"", "\"demo1\"", "\"40\"", "\"1\"", "\"40\"", "\"demo1\"", "\"40\"", "\"1\""]
Then we can just delete \" using :delete method.
Convenient tool to build regexps is http://rubular.com/
When your string is this simple you can use scan + regular expression like this:
result = html.scan(/ProdCode="\d+?"/)
If it is more complex you can use a html parser like nokogiri or oga.

regex replace [ with \[

I want to write a regex in Ruby that will add a backslash prior to any open square brackets.
str = "my.name[0].hello.line[2]"
out = str.gsub(/\[/,"\\[")
# desired out = "my.name\[0].hello.line\[2]"
I've tried multiple combinations of backslashes in the substitution string and can't get it to leave a single backslash.
You don't need a regular expression here.
str = "my.name[0].hello.line[2]"
puts str.gsub('[', '\[')
# my.name\[0].hello.line\[2]
I tried your code and it worked correct:
str = "my.name[0].hello.line[2]"
out = str.gsub(/\[/,"\\[")
puts out #my.name\[0].hello.line\[2]
If you replace putswith p you get the inspect-version of the string:
p out #"my.name\\[0].hello.line\\[2]"
Please see the " and the masked \. Maybe you saw this result.
As Daniel already answered: You can also define the string with ' and don't need to mask the values.

How to correctly replace ereg with preg

I have a list of Mobile devices that I'm using to display content correctly. The depreciated function looks like this:
function detectPDA($query){
$browserAgent = $_SERVER['HTTP_USER_AGENT'];
$userAgents = $this->getBrowserAgentsToDetect(); // comma separated list of devices
foreach ( $userAgents as $userAgent ) {
if(eregi($userAgent,$browserAgent)){
if(eregi("iphone",$browserAgent) || eregi("ipod",$browserAgent) ){
$this->iphone = true;
}else{
$this->pda = true;
}
}
}
}
What is the correct way to replace the eregi functions?
If all the pattern strings ($userAgent and iphone) can be trusted not to contain special regex chars (()[]!|.^${}?*+), then you just surround the eregi regex with slashes (/) and add an i after the last slash (which means "case insensitive").
So:
eregi($userAgent,$browserAgent) --> preg_match("/$userAgent/i",$browserAgent)
eregi("iphone",$browserAgent) --> preg_match('/iphone/i',$browserAgent)
However, are you just trying to match $userAgent as-is within $browserAgent? For example, if a particular $userAgent was foo.bar, would you want the . to match a literal period, or would you want to interpret it in its regex sense ("match any character")?
If the former, I'd suggest you forgo regex entirely and use stripos($haystack,$needle), which searches for the string $needle in $haystack (case-insensitive). Then you don't need to worry about (say) an asterisk in $userAgent being interpreted in the regex sense instead of the literal sense.
If you do use stripos don't forget it can return a 0 which would evaluate to false, so you need to use === false or !== false (see the documentation I linked).

Remove email address from string in Ruby

I have the following code which is supposed to be removing a particular email address from a string if it exists. The problem is i get the error "invalid range "y-d" in string transliteration (ArgumentError)" which I assume is because it's treating my input as a regex. I will need to do this delete by a variable in the actual code, not a string literal but this is a simplified version of the problem.
So how do I properly perform this operation?
myvar = "test1#my-domain.com test2#my-domain.com"
myvar = myvar.delete("test1#my-domain.com")
Try
myvar = "test1#my-domain.com test2#my-domain.com"
myvar = myvar.gsub("test1#my-domain.com", '').strip
String#delete(str) does not delete the literal string str but builds a set out of individual characters of str and deletes all occurrences of these characters. try this:
"sets".delete("test")
=> ""
"sets".delete("est")
=> ""
The hyphen has a special meaning, it defines a range of characters. String#delete("a-d") will delete all occurrences of a,b,c and d characters. Range boundary characters should be given in ascending order: you should write "a-d" but not "d-a".
In your original example, ruby tries to build a character range from y-d substring and fails.
Use String#gsub method instead.
You can do it like this
myvar = "test1#my-domain.com test2#my-domain.com"
remove = "test1#my-domain.com"
myvar.gsub!(remove, "")

Resources