Substitute, replace string with perl - perl

I have string like this:
$string= "only this I need".
I am new in perl, and I tried to translate a PL/SQL code in perl.
My goal is to replace " with a blank space, finally it should look like this:
$string = only this I need
In PL/SQL I use this, and is working very well:
REGEXP_REPLACE(string,'"','');
In perl I tried this, but is not working: $string=~s/"/''; receiving an error.
Please, help me, tell me what I need to read to do my job properly?

Try this it should work:
use strict;
use warnings;
my $string= '"only this I need"';
print "$string \n"; #prints "only this I need"
$string =~ s/"/ /g;
print "$string \n"; #prints only this I need

This is a way to remove quotes from string:
my $string= '"only this I need"';
$string =~ m/"([^"]*)"/;
print "$1\n";
In case if you know the first and last character is quotes, you can do this without using regex, just use substr:
my $string= '"only this I need"';
$string = substr $string, 1, -1;
print "$string\n";

Related

Split, insert and join

Here's I want to archive. I want to split a one-liner comma-separated and insert #domain.com then join it back as comma-separated.
The one-liner contains something like:
username1,username2,username3
and I want to be something like:
username1#domain.com,username2#domain.com,username3#domain.com
So my Perl script that I tried which doesn't not work properly:
my $var ='username1,username2,username3';
my #tkens = split /,/, $var;
my #user;
foreach my $tken (#tkens) {
push (#user, "$tken\#domain.com");
}
my $to = join(',',#user);
Is there any shortcut on this in Perl and please post sample please. Thanks
Split, transform, stitch:
my $var ='username1,username2,username3';
print join ",", map { "$_\#domain.com" } split(",", $var);
# ==> username1#domain.com,username2#domain.com,username3#domain.com
You could also use a regular expression substitution:
#!/usr/bin/perl
use strict;
use warnings;
my $var = "username1,username2,username3";
# Replace every comma (and the end of the string) with a comma and #domain.com
$var =~ s/$|,/\#domain.com,/g;
# Remove extra comma after last item
chop $var;
print "$var\n";
You already have good answers. Here I am just telling why your script is not working. I didn't see any print or say line in your code, so not sure how you are trying to print something. No need of last line in your program. You can simply suffix #domain.com with each value, push to an array and print it with join.
#!/usr/bin/perl
use strict;
use warnings;
my $var = 'username1,username2,username3';
my #tkens = split ',', $var;
my #user;
foreach my $tken (#tkens)
{
push #user, $tken."\#domain.com"; # `.` after `$tken` for concatenation
}
print join(',', #user), "\n"
Output:
username1#domain.com,username2#domain.com,username3#domain.com

Splitting Perl string and adding _ in between

Question. I am trying to read in perl string from command line e.g. "abcdef" and then split this into "a_b_c_d_e_f".
I am struggling with logic part. any ideas?
#!/usr/bin/perl
while($line=<STDIN>){
chomp $line;
split $line;
join ("_", $line);
print $line;
}
The split manpage actually includes exactly this example:
print join(':', split('', 'abc')), "\n";
Adjusting to use _ instead of : and $line instead of 'abc', we get:
print join('_', split('', $line)), "\n";
The most important point is that split doesn't modify its arguments, it just returns a list, and join doesn't modify its arguments, it just returns a string. So it never makes sense to call split or join without using the return-value.
What you need is
print join('_', split //, $line), "\n";
One-liner:
print join('_', split('', $line)), '\n';
You can read more about perl's split() function here.
Unless you must use split, you can use a between-character substitution for this:
use strict;
use warnings;
my $string = 'abcdef';
$string =~ s/(?<=.)(?:)(?=.)/_/g;
print $string;
Output:
a_b_c_d_e_f
Hope this helps!

Matching in Perl

I am trying to get text in between two dots of a line, but my program returns the entire line.
For example: I have text which looks like:
My sampledata 1,2 for perl .version 1_1.
I used the following match statement
$x =~ m/(\.)(.*)(\.)/;
My output for $x should be version 1_1, but I am getting the entire line as my match.
In your code, the value of $x will not change after the match.
When $x is successfully matched with m/(.)(.*)(.)/, your three capture groups will contain '.', 'version 1_1' and '.' respectively (in the order given). $2 will give you 'version 1_1'.
Considering that you might probably only want the part 'version 1_1', you need not capture the two dots. This code will give you the same result:
$x =~ m/\.(.*)\./;
print $1;
Try this:
my $str = "My sampledata 1,2 for perl .version 1_1.";
$str =~ /\.\K[^.]+(?=\.)/;
print $&;
The period must be escaped out of a character class.
\K resets all that has been matched before (you can replace it by a lookbehind (?<=\.))
[^.] means any character except a period.
For several results, you can do this:
my $str = "qwerty .target 1.target 2.target 3.";
my #matches = ($str =~ /\.\K[^.]+(?=\.)/g);
print join("\n", #matches);
If you don't want to use twice a period you can do this:
my $str = "qwerty .target 1.target 2.target 3.";
my #matches = ($str =~ /\.([^.]+)\./g);
print join("\n", #matches)."\n";
It should be simple enough to do something like this:
#!/usr/bin/perl
use warnings;
use strict;
my #tests = (
"test one. get some stuff. extra",
"stuff with only one dot.",
"another test line.capture this. whatever",
"last test . some data you want.",
"stuff with only no dots",
);
for my $test (#tests) {
# For this example, I skip $test if the match fails,
# otherwise, I move on do stuff with $want
next if $test !~ /\.(.*)\./;
my $want = $1;
print "got: $want\n";
}
Output
$ ./test.pl
got: get some stuff
got: capture this
got: some data you want

Why does 'chop' not work with <STDIN>?

I am trying to figure out why the chop function is not working for me when I try to take input from the user:
my $string = <STDIN>;
my $chr = chop($string);
print "String: $string\n";
print "Char: $chr\n";
output
perl chop.pl
hello
String: hello
Char:
But if I use a string, then it works!
my $string = "frong";
my $chr = chop($string);
print "String: $string\n";
print "Char: $chr\n";
output
[583]
perl chop.pl
String: fron
Char: g
When you pass input from console, chop is chopping the newline that is at the end of the string, which is present when you hit Enter. While your string does not contain that.
What you're chop()'ing is the newline at the end of the string. To remove the newline upon assignment from STDIN:
chomp(my $string = <STDIN>);
In other words, your program should look like this:
chomp(my $string = <STDIN>);
my $chr = chop($string);
print "String: $string\n";
print "Char: $chr\n";
Checking the perl documentation for these two functions chop and chomp might just do.
chomp
chomp This safer version of "chop" removes any trailing string that
corresponds to the current value of $/ (also known as
$INPUT_RECORD_SEPARATOR in the "English" module.
chop
chop Chops off the last character of a string and returns the
character chopped.
Hope this help
If you're printing diagnostics to show variable contents, put some form of delimiter around them, then you'd see the newline in your $chr example.
eg.
print "String: \"$string\"\n";
print "Char: \"$chr\"\n";

Why isn't Perl's tr/// doing what I want?

I am using Perl for a script that takes in input as two short strings of DNA. As an output, I concatenate the two strings strings then print the second string lined up over its copy at the end of the concatenated string. For example: if input string are AAAA and TTTTT then print:
AAAAATTTTT
TTTTT
I know there are other ways to do this but I am curious to know why my use of tr/// isn't working.
The code for the program is:
use strict;
use warnings;
print "enter a DNA sequence \n";
$DNA1=<>; #<> shorthand for STDIN
$DNA1=~ s/\r?\n?$//;
print $DNA1 "\n\n";
print "enter second DNA sequence \n";
$DNA2=<>;
$DNA2=~ s/\r?\n?$//;
print $DNA2 "\n\n";
$DNA= join("",($DNA1,$DNA2));
print "Both DNA sequences are \"$DNA\" \n\n";
$DNA3=$DNA1;
$DNA3=~ tr/ATCGatcg//;
print $DNA3 "\n\n";
$DNA4= join("",($DNA3,$DNA2));
print $DNA4 "\n\n";
exit;
Your tr changes any of ACTGatcg and removes them. I think you want
$DNA3 =~ tr/atcgATCG/ /;
You need to put a space in the second half of the tr command.
Alternatively, it seems that what you're trying to do is create a variable containing as many spaces as there were characters in the first string:
my $spaces = ' ' x length($DNA1);
It might just be a simple syntax error. Try:
$DNA3 =~ tr/ATCGatcg/ /;
where the second slash separates your two translation entities, and you have a space character between the second and third slashes.
Good luck!
Edit: my mistake - misunderstood what you wanted to do. Answer adjusted accordingly :)
Is this the program that you want?
#!perl
my $s1 = 'AAAAAAAAA';
my $s2 = 'TCGAGCTA';
print
$s1, $s2, "\n",
' ' x length( $s1 ), $s2, "\n";