Trivial search/replacement in Perl without error? - perl

How to simply do a search/replace in Perl? The following example doesn't work:
#!/usr/bin/env perl
use strict;
use warnings;
my $text = '***/**/*abc*/***//*';
my $search = '/*abc*/';
my $replace = '#def#';
print "$text\n";
$text =~ s/$search/$replace/g;
print "$text\n";

$search is not treated as a string, but as a regular expression. The character * has a special meaning in regular expressions so you need to quote it. Try:
$search = quotemeta '/*abc*/';

Make sure that content of $search has quoted meta-chars by using \Q or quotemeta in order to be treated as literal string,
$text =~ s/\Q$search/$replace/g;

Related

Using a Perl variable as the substitute expression

I want to read the substitute expressions flexibly from external data,
so my problem could be reduced to the following:
my $pattern = "s/a/b/g";
my $string = "abcd";
$string =~ $pattern;
print("$string\n");
This is not functioning, but where is my problem?
Or does it even have no solution?
$pattern doesn't contain a regex pattern; it contains a bit of Perl source code. To evaluate Perl code, you need eval EXPR (or do or require).
Requiring Perl code from a user is a bad idea, though. Instead, I recommend the requiring the pattern and the replacement separately, as in the following:
my $pattern = 'a';
my $replacement = 'b';
my $string = 'abcd';
$string =~ s/$pattern/$replacement/g;
Use a function from String::Substitution if you want to allow $1 and such to be allowed in the replacement expression.
use String::Substitution qw( gsub_modify );
my $pattern = '(a)(b)';
my $replacement = '$2$1';
my $string = 'abcd';
gsub_modify($string, $pattern, $replacement);

How to regex one word from escaped and closed parenthesis?

I am trying to get "loginuser" value from this line. Please suggest
my $ln = CN=xuser\\,user(loginuser),OU=Site-Omg,OU=Accounts_User,OU
if (/ln: (\S.*\S)\s*$/)
{ print $1; }
This will work
use strict;
use warnings;
my $ln = qq{CN=xuser\\,user(loginuser),OU=Site-Omg,OU=Accounts_User,OU};
print $1 . "\n" if $ln =~ /\(([^)]*)/
Things to note
I have used strict and warnings to show any errors in the script( would have been very useful for your original)
I have used qq{...} to quote the original string
I have ended the line with ;
I have performed the regex match on $ln instead of $_ using $ln =~ ...
I have written correct regex to get the match.

Unmatched ) in reg when using lc function

I am trying to run the following code:
$lines = "Enjoyable )) DAY";
$lines =~ lc $lines;
print $lines;
It fails on the second line where I get the error mentioned in the title. I understand the brackets are causing the trouble. I think I could use "quotemeta", but the thing is that my string contains info that I go on to process later, so I would like to keep the string intact as far as possible and not tamper with it too much.
You have two problems here.
1. =~ is used to execute a specific set of operations
The =~ operator is used to either match with //, m//, qr// or a string; or to substitute with s/// or tr///.
If all you want to do is lowercase the contents of $lines then you should use = not =~.
$lines = "Enjoyable )) DAY";
$lines = lc $lines;
print $lines;
2. Regular expressions have special characters which must be escaped
If you want to match $lines against a lower case version of $Lines, which should return true if $lines was already entirely lower case and false otherwise, then you need to escape the ")" characters.
#!/usr/bin/env perl
use strict;
use warnings;
my $lines = "enjoyable )) day";
if ($lines =~ lc quotemeta $lines) {
print "lines is lower case\n";
}
print $lines;
Note this is a toy example trying to find a reason for doing $lines =~ lc $lines - It would be much better (faster, safer) to solve this with eq as in $lines eq lc $lines.
See perldoc -f quotemeta or http://perldoc.perl.org/functions/quotemeta.html for more details on quotemeta.
=~ is used for regular expressions. "lc" is not part of regex, it's a function like this: $new = lc($old);
I don't recall the regex operator for lowercase, because I use lc() all the time.

regular expression to match file path in perl

I'm new to Perl and i'm trying to extract the path of a file. Please help me with a suitable regular expression, this is my code:
$string = "D:/EZ-VPN/NKEMSL0-V02.txt------vpnclient server 156.37.253.97";
I want to extract "D:/EZ-VPN/NKEMSL0-V02.txt" and "156.37.253.97" and store it in 2 scalar variables. Please suggest a regular expression to extract these.
thanks in advance
#!/usr/bin/perl
use strict;
my $string = "D:/EZ-VPN/NKEMSL0-V02.txt------vpnclient server 156.37.253.97";
$string =~ m/(.*?)--+.* (\d+\.\d+\.\d+\.\d+)/;
print $1."\n";
print $2."\n";
This should work for you.
Perl gathers the results from the regex's brackes (so called capture groups) in the $1, $2 ... $n variables.
The filename is in $1, the IP adress is in $2.
Using the string of 6 consecutive dashes to mark the end of the path:
my($path, $ipaddress) = ($string =~ m/(.*?)------.* (\d+\.\d+\.\d+\.\d+)/);
Test script:
#!/usr/bin/env perl
use strict;
use warnings;
my $string = "D:/EZ-VPN/NKEMSL0-V02.txt------vpnclient server 156.37.253.97";
my($path, $ipaddress) = ($string =~ m/(.*?)------.* (\d+\.\d+\.\d+\.\d+)/);
print "path = $path; IP = $ipaddress\n";
Output:
path = D:/EZ-VPN/NKEMSL0-V02.txt; IP = 156.37.253.97
my ($x, $y) = split /------/, $string;
my ($z) = $y =~ /(\S+)\z/;

Check for spaces in perl using regex match in perl

I have a variable how do I use the regex in perl to check if a string has spaces in it or not ? For ex:
$test = "abc small ThisIsAVeryLongUnbreakableStringWhichIsBiggerThan20Characters";
So for this string it should check if any word in the string is not bigger than some x characters.
#!/usr/bin/env perl
use strict;
use warnings;
my $test = "ThisIsAVeryLongUnbreakableStringWhichIsBiggerThan20Characters";
if ( $test !~ /\s/ ) {
print "No spaces found\n";
}
Please make sure to read about regular expressions in Perl.
Perl regular expressions tutorial - perldoc perlretut
You should have a look at the perl regex tutorial. Adapting their very first "Hello World" example to your question would look like this:
if ("ThisIsAVeryLongUnbreakableStringWhichIsBiggerThan20Characters" =~ / /) {
print "It matches\n";
}
else {
print "It doesn't match\n";
}
die "No spaces" if $test !~ /[ ]/; # Match a space
die "No spaces" if $test =~ /^[^ ]*\z/; # Match non-spaces for entire string
die "No whitespace" if $test !~ /\s/; # Match a whitespace character
die "No whitespace" if $test =~ /^\S*\z/; # Match non-whitespace for entire string
To find the length of the longest unbroken sequence of non-space characters, write this
use strict;
use warnings;
use List::Util 'max';
my $string = 'abc small ThisIsAVeryLongUnbreakableStringWhichIsBiggerThan20Characters';
my $max = max map length, $string =~ /\S+/g;
print "Maximum unbroken length is $max\n";
output
Maximum unbroken length is 61