How do I replace "\" with "//" in Perl? - perl

I want to substitute, the "\" that appears in the Windows directory link to a "/".
I tried using s//\////g, but it doesn't seem to do the trick.

s[\\][//]g
\ needs to be escaped in a regex
/ does not
Avoid using / to delimit regex sections when using / in the expression itself (it makes things much more readable!)
... but you should probably use something like Path::Class.

First of all, using a different separator than \ will make your regex more readable.
Then you have to replace the \ with \\, or it will be used to escape the following character (a / in the regex you are using).
$link =~ s|\\|//|g;

I think this should do it:`
$str =~ s{\\}{//}g;

Related

Notepad++ User Defined language for Perl

I'm trying to create my own language defined theme for Perl scripts so everything gets colorcoded the way I want.
The issue I'm having is that regexp sections are not getting colored the way I need them by using a delimiter in the UDL GUI.
Exmaple:
if($string =~ /^This is a string$/){
print "worked!!!!!!\n";
}
I want "/^This is a string$/" colorcoded in red, but the delimiter I created takes the whole line after =~ /. How can I force Notepad++ to only colorcode until the last "/" on the line?
Here is my delimiter configuration. keep in mind that I already tried "/" instead of ((EOL)) and it didn't work. Thank you
I use this as one of my delimiters in my AWK definition:
Open: ~/ (/ ,/ !~/
Escape: \ \ \ \
Close: / / / /
It isn't ideal, but it works well enough for me.

How to quote $1 in yasnippet

Suppose, I have the following yasnippet:
my $dir = __FILE__;
$dir =~ s/(.*)\/.*/$1/;
$1 here is the regular expression first match. Not yasnippet special symbol. How can I quote it, so it is inserted into the code as is?
From the documentation:
Arbitrary text can be included as the content of a template. They are usually interpreted as plain text, except $ and `. You need to use \ to escape them: \$ and \`. The \ itself may also needed to be escaped as \\ sometimes.
So use \$ to get a literal '$' in your snippet.

Recursive Search and replace with / and '

I have searched and not found a solution so sorry if this has been answered before, I'm not great at shell.
I'm trying to do a recursive search and replace in all files via SSH.
So far I've got this:
find . -type f | xargs -d "\n" perl -pi -e 's/$this->helper('catalog/product')->getPriceHtml/$this->getPriceHtml/g'
I'm trying to replace this:
$this->helper('catalog/product')->getPriceHtml
with this:
$this->getPriceHtml
But I think its not working because of the slashes and single quotes. I have tried escaping these with \ but to no avail, any ideas?
An alternate delimiter for the s operator could be used to avoid picket fences. $this will be considered to be a variable unless the $ is escaped. The parentheses have to be escaped as well. Else they form a capture group. Since it is a one-liner and quotes have been exhausted, single-quotes have been encoded using hexadecimal escapes. The following should work:
s{\$this->helper\(\x{27}catalog/product\x{27}\)->getPriceHtml}{\$this->getPriceHtml}g;
Or:
s{(?<=\$this)->helper\(\x{27}catalog/product\x{27}\)(?=->getPriceHtml)}{}g;

Perl string sub

I want to replace something with a path like C:\foo, so I:
s/hello/c:\foo
But that is invalid.
Do I need to escape some chars?
Two problems that I can see.
Your first problem is that your s/// replacement is not terminated:
s/hello/c:\foo # fatal syntax error: "Substitution replacement not terminated"
s/hello/c:\foo/ # syntactically okay
s!hello!c:\foo! # also okay, and more readable with backslashes (IMHO)
Your second problem, the one you asked about, is that the \f is taken as a form feed escape sequence (ASCII 0x0C), just as it would be in double quotes, which is not what you want.
You may either escape the backslash, or let variable interpolation "hide" the problem:
s!hello!c:\\foo! # This will do what you want. Note double backslash.
my $replacement = 'c:\foo' # N.B.: Using single quotes here, not double quotes
s!hello!$replacement!; # This also works
Take a look at the treatment of Quote and Quote-like Operators in perlop for more information.
If I understand what you're asking, then this might be something like what you're after:
$path = "hello/there";
$path =~ s/hello/c:\\foo/;
print "$path\n";
To answer your question, yes you do need to double the backslash because \f is an escape sequence for "form feed" in a Perl string.
The problem is that you are not escaping special characters:
s/hello/c:\\foo/;
would solve your problem. \ is a special character so you need to escape it. {}[]()^$.|*+?\ are meta (special) characterss which you need to escape.
Additional reference: http://perldoc.perl.org/perlretut.html

How do I escape special characters for a substitution in a Perl one-liner?

Is there some way to replace a string such as #or * or ? or & without needing to put a "\" before it?
Example:
perl -pe 'next if /^#/; s/\#d\&/new_value/ if /param5/' test
In this example I need to replace a #d& with new_value but the old value might contain any character, how do I escape only the characters that need to be escaped?
You have several problems:
You are using \b incorrectly
You are replacing code with shell variables
You need to quote metacharacters
From perldoc perlre
A word boundary ("\b") is a spot between two characters that has a "\w" on one side of it
Neither of the characters # or & are \w characters. So your match is guaranteed to fail. You may want to use something like s/(^|\s)\#d\&(\s|$)/${1}new text$2/
(^|\s) says to match either the start of the string (^)or a whitespace character (\s).
(\s|$) says to match either the end of the string ($) or a whitespace character (\s).
To solve the second problem, you should use %ENV.
To solve the third problem, you should use the \Q and \E escape sequences to escape the value in $ENV{a}.
Putting it all together we get:
#!/bin/bash
export a='#d&'
export b='new text'
echo 'param5 #d&' |
perl -pe 'next if /^#/; s/(^|\s)\Q$ENV{a}\E(\s|$)/$1$ENV{b}$2/ if /param5/'
Which prints
param5 new text
As discussed at perldoc perlre:
...Today it is more common to use the quotemeta() function or the "\Q" metaquoting
escape sequence to disable all metacharacters' special meanings like this:
/$unquoted\Q$quoted\E$unquoted/
Beware that if you put literal backslashes (those not inside interpolated variables) between "\Q" and "\E", double-quotish backslash interpolation may
lead to confusing results. If you need to use literal backslashes within "\Q...\E", consult "Gory details of parsing quoted constructs" in perlop.
You can also use a ' as the delimiter in the s/// operation to make everything be parsed literally:
my $text = '#';
$text =~ s'#'1';
print $text;
In your example, you can do (note the single quotes):
perl -pe 's/\b\Q#f&\E\b/new_value/g if m/param5/ and not /^ *#/'
The other answers have covered the question, now here's your meta-problem: Leaning Toothpick Syndrome. Its when the delimiter and escapes start to blur together:
s/\/foo\/bar\\/\/bar\/baz/
The solution is to use a different delimiter. You can use just about anything, but balanced braces work best. Most editors can parse them and you generally don't have to worry about escaping.
s{/foo/bar\\}{/bar/baz}
Here's your regex with braced delimiters.
s{\#d\&}{new_value}
Much easier on the eyeholes.
If you really want to avoid typing the \s, put your search string into a variable and then use that in your regex instead. You don't need quotemeta or \Q ... \E in that case. For example:
my $s = '#d&';
s/$s/new_value/g;
If you must use this in a one-liner, bear in mind that you will have to escape the $s if you use "s to contain your perl code, or escape the 's if you use 's to contain your perl code.
If you have a string like
my $var1 = abc$123
and you want to replace it with abcd then you have to use \Q \E. If you don't then no matter what perl doesn't replace the string.
This is the only thing that worked for me.
my $var2 = s/\Q$var1\E/abcd/g;