how to replace the special character with escape character - perl

my $c= 'ODD_`!"£$%^&*(){}][##;:/?.>,<|\'
I want to replace all of them into as special character
how achiveve this in faster way ..
my $c= 'ODD_\`\!\"\£\$\%\^\&\*\(\)\{\}\]\[\#\,\;\:\/\?\.\>\,\<\|\\'

Use quotemeta:
#!/usr/bin/env perl
use warnings; use strict;
my $c = 'ODD_`!"£$%^&*(){}][##;:/?.>,<|\\';
print quotemeta($c), "\n";
Note that your definition of $c would not compile as you have to escape \ even in single quoted strings.

While I think that Sinan's answer is correct for what I am assuming you need (based on your list of characters to escape), for completeness I will add the module URI::Escape which escapes the metacharacters in HTML text. It does seem that it has some facility to specify the unsafe characters though, so perhaps it could help you too.

Related

Perl delete a character from a string unless it is a duplicate

What is the cleanest/simplest way to remove a particular character from a string unless it is repeated once.
For example given the following string:
'it''s 'simple'
I expect:
it's simple
For my usage there shall never be more than two ' characters in a row.
Use a negative look-ahead assertion.
#!/use/bin/perl
use strict;
use warnings;
use feature 'say';
$_ = "'it''s simple'";
say;
s/'(?!')//g;
say;
'(?!') means "a single quote that isn't followed immediately by another single quote".
Output:
'it''s simple'
it's simple
use warnings;
use strict;
my $text = q!'it''s 'simple'!;
$text =~ s/'('?)/$1/g;
print "$text\n";
So in the regex '('?), it will match - and remove - the first ' and if followed by another, will capture it and place it in the result.
This version will handle each one or two apostrophe group separately (because OP used the term "duplicate" instead of "multiple"). If you want to replace any 2+ apostrophe sequence with a single one, use the regex '('?)'* instead.

Perl regex for allowing all the special charecters

The environment I am working is on PCRE which supports Perl syntax.
I want to build a regular expression which supports all the charecters and special charecters.
I have tried
(.*)
But it does not work.
For example. I am trying to redirect
From
https://oldaddress.com/select.do?cyuf=err%3Errt.com%3fsfds%4A222-3424234&p=66&j=8
To
https://newsite.com/select.do?cyuf=err%3Errt.com%3fsfds%4A222-3424234&p=66&j=8
The old site oldaddress.com successfully redirects to newsite.com but the URI part select.do?cyuf=err%3Errt.com%3fsfds%4A222-3424234&p=66&j=8 does not remain in it.
I have used regEx =~ (^.*) to handle the URI part but the regex does not support all the special characters.
I would like to implement this regEx in Perl.
Your problem is almost certainly not with your regex. The query parameters don't change, so they shouldn't be included in the regex at all as this Perl code will demonstrate:
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
my $url = 'https://oldaddress.com/select.do?cyuf=err%3Errt.com%3fsfds%4A222-3424234&p=66&j=8';
my $new_url = 'https://newsite.com/select.do?cyuf=err%3Errt.com%3fsfds%4A222-3424234&p=66&j=8';
$url =~ s/oldaddress/newsite/;
if ($url eq $new_url) {
say "Looks like that worked";
} else {
say "Looks like you've got a problem";
}
I'm only changing the domain, so that's all I need to refer to in the regex.
If your query string isn't surviving the transformation, then that problem is down to some other problem in the technology that you are using. Without knowing more about what you're doing, we really can't be any more help.
Update: From Sawyer's comment
but how to handle special charecters ?, % using Regex using Perl
You don't seem to be reading what people are telling you.
Your regex doesn't need to handle ?, % or other special characters. Your regex only needs to deal with the bits of your string that are changing - that's the domain names and they don't include these characters.
% has no special meaning in Perl regular expressions.
? has a special meaning, you avoid that by escaping it with a backslash (so use \?).
A dot (.) in a Perl regular expression matches any character except a newline. It matches ? and % without any problems at all.
Your problem is not with your regex; it is somewhere else in your system. But because you are being so mysterious about what you're doing and how you're doing it, we really can't be any more help.
Update2: Here's another version of my program which demonstrates (.*) matching ? and %. But I can't emphasise enough that you don't need to do this.
#!/usr/bin/perl
use strict;
use warnings;
use 5.010;
my $url = 'https://oldaddress.com/select.do?cyuf=err%3Errt.com%3fsfds%4A222-3424234&p=66&j=8';
my $new_url = 'https://newsite.com/select.do?cyuf=err%3Errt.com%3fsfds%4A222-3424234&p=66&j=8';
$url =~ s/(.*)oldaddress(.)/${1}newsite${2}/;
if ($url eq $new_url) {
say "Looks like that worked";
} else {
say "Looks like you've got a problem";
}

perl split interesting behavior

can somebody explain this weird behavior:
I hava path in a string and I want to split it for each backslash
my $path = "D:\Folder\AnotherFolder\file.txt";
my #folders = split('\', $path);
in the case above it won't work not even if escaping the backslash like this:
my #folders = split('\\', $path);
but in the case of a regexp it will work:
my #folders = split( /\\/, $path);
why is so?
I think amon gave the best literal answer to your question in his comment:
more explicitly: strings and regexes have different rules for escaping. If a string is used in place of a regex, the string literals suffer from double escaping
Meaning that split '\\' uses a string and split /\\/ uses a regex.
As a practical answer, I wanted to add this:
Perhaps you should consider using a module suited for splitting paths. File::Spec is a core module in Perl 5. And also, you have to escape backslash in a double quoted string, which you have not done. You can also use single quotes, which looks a bit better in my opinion.
use strict;
use warnings;
use Data::Dumper;
use File::Spec;
my $path = 'D:\Folder\AnotherFolder\file.txt'; # note the single quotes
my #elements = File::Spec->splitdir($path);
print Dumper \#elements;
Output:
$VAR1 = [
'D:',
'Folder',
'AnotherFolder',
'file.txt'
];
If you look at the documentation by running:
perldoc -f split
you will see three forms of arguments that split can take:
split /PATTERN/,EXPR,LIMIT
split /PATTERN/,EXPR
split /PATTERN/
This means that even when you pass split a string as the first argument, perl is coercing it into a regex.
If we look at the warnings we get when trying to do something like this in re.pl:
$ my $string_with_backslashes = "Hello\\there\\friend";
Hello\there\friend
$ my #arry = split('\\', $string_with_backslashes);
Compile error: Trailing \ in regex m/\/ at (eval 287) line 6.
we see that first, '\\' is interpolated as a backslash escape followed by an actual backslash, which evaluates to a single backslash.
split then puts the backslash we gave it, and coerces it to a regex as if we had written:
$ my #arry = split(/\/, $string_with_backslashes);
which doesn't work because there is only a single backslash which is interpreted as simply escaping the forward slash after it (without having a terminating /) to show that the regex has ended.
One of the neater ways to extract the elements of a path is to extract all sequences of characters other than a path separator.
use strict;
use warnings;
my $path = 'D:\Folder\AnotherFolder\file.txt';
my #path = $path =~ m([^/\\]+)g;
print "$_\n" for #path;
output
D:
Folder
AnotherFolder
file.txt
When split is used in the form of split STRING and not split REGEX, the string is being converted into a regex. In your case split '\\' will be converted to split /\/ since the first backslash is considered an escape character.
The correct way to do it is split '\\\\' which will be translated to split /\\/.

Using quote-like-operators or quotes in the perl's printf

Reading perl sources I saw many times the next construction:
printf qq[%s\n], getsomestring( $_ );
But usually it is written as
printf "%s\n", getsomestring( $_ );
The question:
is here any "good practice" what is the correct way, and if yes
when is recommended to use the longer qq[...] vs the "..."
or it is only pure TIMTOWTDI?
The perlop doesn't mention anything about this.
You can use qq() as an alternative double quote method, such as when you have double quotes in the string. For example:
"\"foo bar\""
Looks better when written
qq("foo bar")
When in the windows cmd shell, which uses double quotes, I often use qq() when I need interpolation. For example:
perl -lwe "print qq($foo\n)"
The qq() operator -- like many other perl operators such as s///, qx() -- is also handy as you demonstrate because it can use just about any character as its delimiter:
qq[this works]
qq|as does this|
qq#or this#
This is handy for when you have many different delimiters in the string. For example:
qq!This is (not) "hard" to quote!
As for best practice, I would say use whatever is more readable.
I always use qq[...] when there are quotes in the strings, example:
qq["here you are", he said]
If not, for me is more readable the use of ""

How do I convert UNIX path to DOS path

Need a regex or some other method to convert UNIX path to DOS path.
I have
C:/My Document/Photo.gif
Need
C:\My Document\Photo.gif
#!/usr/bin/perl
use strict; use warnings;
use File::Spec::Win32;
print File::Spec::Win32->canonpath('C:/My Document/Photo.gif'), "\n";
This is the regular expression
s/\//\\/g
First off, you do not normally need to do that mapping unless you are going to invoke something via cmd.exe; the Windows API is perfectly happy with slashes instead of backslashes in file names (but cmd.exe insists that slash starts an option).
Then, the direct answer to your question is perhaps:
my $file = "C:/My Documents/Photo.gif";
$file =~ s{/}{\\}g;
print "$file\n";
Just replace / with \. Though I must point out that you can use forward-slashes in Windows.
A bit superfluous, but you could use tr instead of a regex:
tr!\\!/!;