Unmatched ) in reg when using lc function - perl

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.

Related

using two search and replace regex commands in Perl

In a file, I have to replace
.L1 to L_xx_1
.L2 to L_xx_2
.L3 to L_xx_3
...
and
.LC1 to LC_xx_1
.LC2 to Lc_xx_2
.LC3 to LC_xx_3
...
For these two search and replacements I have two different Perl scripts containing following two different loops:
for ($i=0; $currentLine=<file>; $i++) {
$currentLine =~ s/.L(\d+)/L_$ARGV[1]_$1/gi;
print $currentLine;
}
and
for ($i=0; $currentLine=<file>; $i++) {
$currentLine =~ s/.LC(\d+)/LC_$ARGV[1]_$1/gi;
print $currentLine;
}
respectively.
Can I merge these two loops into one by merging two S commands into one.
Yes, you can combine the 2 substitutions into one with a different regular expression. You can capture the "L" followed by an optional "C".
use warnings;
use strict;
my $str = 'xx';
while (my $currentLine = <DATA>) {
$currentLine =~ s/\.(LC?)(\d+)/$1_${str}_$2/gi;
print $currentLine;
}
__DATA__
.L1
.L2
.L3
.LC1
.LC2
.LC3
This prints:
L_xx_1
L_xx_2
L_xx_3
LC_xx_1
LC_xx_2
LC_xx_3
Note that I escaped the first character (the period). This will only match a literal period.
Modify your regex to
$currentLine =~ s/\.L(C?)(\d+)/L$1_$ARGV[1]_$2/gi;

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.

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

Perl, pattern matching and metacharacters

I am trying to match two things which both are full of metacharacters that needs to be used as 'Literal' in my match pattern. \Q is suppose to quote all metacharacter in a string until \E...but it doesn't work.
Whats up with that?
this is the line that gives me trouble : if (/\Q$prev\E/ !~ /\Q$ww[0]\E/) {
Absent the use of =~ or !~,
/.../
is short for
$_ =~ m/.../
so
/\Q$prev\E/ !~ /\Q$ww[0]\E/
is short for
($_ =~ /\Q$prev\E/) !~ /\Q$ww[0]\E/
which is equivalent to one of the following depending on whether the left regex match succeeds or not:
"" !~ /\Q$ww[0]\E/
"1" !~ /\Q$ww[0]\E/
You simply want:
$prev !~ /\Q$ww[0]\E/ # $ww[0] doesn't contains $prev
If you actually want
$prev !~ /^\Q$ww[0]\E\z/ # $ww[0] isn't equal to $prev
then you can simplify that to
$prev ne $ww[0] # $ww[0] isn't equal to $prev
By the way, always use use strict; use warnings;. It may have identified a problem here (but not necessarily, depending on the value of $_).
It looks like you want to compare a string in $prev to one in $ww[0]. If this is the case, a regex match should look like this:
$result = $prev !~ /\Q$ww[0]\E/
$result will return 1 if $prev is not the same as whatever is in www[0], ignoring metacharacters.
However if that is all you wanted to do, you might as well use ne:
if ($prev ne $ww[0]){
#do this if $prev and $ww[0] are not the same
}
Also, as #toolic has mentioned, add the following line to the top of your script:
use warnings;
This will give you some feedback on possible problems in your scripts.

perl blank substitution in a string

I have this two kind of strings:
EVASA 2144
IN ELABORAZIONE 16278
I need some perl script to substitute all the blanks with just one.
The output I need is:
EVASA 2144
Any suggestion?
You can use a very simple regex:
#!/usr/bin/perl
use strict;
my $line = 'EVASA 2144';
# This is the line that actually does the work
$line =~ s/\s+/ /g;
print $line, "\n";
My suggestion would be that you spend some time reading the Regular Expression tutorial that is distributed with every modern version of Perl.
$a = "hello \t world";
$a =~ s/\s+/ /;
print $a;
if you may have multiple places in the string where you want the substitution to take place, use
$a = "hello \t world hi";
$a =~ s/\s+/ /g;
print $a;
You can also use the troperator with the s Option, this can do more things for you (transforming characters), probably faster than the regexp approach
$a =~ tr/ \t/ /s;
Explanation can be found in the perlop manpage:
perldoc perlop