regular expression to match file path in perl - 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/;

Related

Is there a better way to count occurrence of char in a string?

I felt there must a better way to count occurrence instead of writing a sub in perl, shell in Linux.
#/usr/bin/perl -w
use strict;
return 1 unless $0 eq __FILE__;
main() if $0 eq __FILE__;
sub main{
my $str = "ru8xysyyyyyyysss6s5s";
my $char = "y";
my $count = count_occurrence($str, $char);
print "count<$count> of <$char> in <$str>\n";
}
sub count_occurrence{
my ($str, $char) = #_;
my $len = length($str);
$str =~ s/$char//g;
my $len_new = length($str);
my $count = $len - $len_new;
return $count;
}
If the character is constant, the following is best:
my $count = $str =~ tr/y//;
If the character is variable, I'd use the following:
my $count = length( $str =~ s/[^\Q$char\E]//rg );
I'd only use the following if I wanted compatibility with versions of Perl older than 5.14 (as it is slower and uses more memory):
my $count = () = $str =~ /\Q$char/g;
The following uses no memory, but might be a bit slow:
my $count = 0;
++$count while $str =~ /\Q$char/g;
Counting the occurences of a character in a string can be performed with one line in Perl (as compared to your 4 lines). There is no need for a sub (although there is nothing wrong with encapsulating functionality in a sub). From perlfaq4 "How can I count the number of occurrences of a substring within a string?"
use warnings;
use strict;
my $str = "ru8xysyyyyyyysss6s5s";
my $char = "y";
my $count = () = $str =~ /\Q$char/g;
print "count<$count> of <$char> in <$str>\n";
In a beautiful* Bash/Coreutils/Grep one-liner:
$ str=ru8xysyyyyyyysss6s5s
$ char=y
$ fold -w 1 <<< "$str" | grep -c "$char"
8
Or maybe
$ grep -o "$char" <<< "$str" | wc -l
8
The first one works only if the substring is just one character long; the second one works only if the substrings are non-overlapping.
* Not really.
toolic has given a correct answer, but you might consider not hardcoding your values to make the program reusable.
use strict;
use warnings;
die "Usage: $0 <text> <characters>" if #ARGV < 1;
my $search = shift; # the string you are looking for
my $str; # the input string
if (#ARGV && -e $ARGV[0] || !#ARGV) { # if str is file, or there is no str
local $/; # slurp input
$str = <>; # use diamond operator
} else { # else just use the string
$str = shift;
}
my $count = () = $str =~ /\Q$search\E/gms;
print "Found $count of '$search' in '$str'\n";
This will allow you to use the program to count for the occurrence of a character, or a string, inside a string, a file, or standard input. For example:
count.pl needles haystack.txt
some_process | count.pl foo
count.pl x xyzzy

How to substitute " with " in perl

I want to substitute all " in the string $input with /" and I come up with the following code:
#!/usr/bin/perl -w
use CGI;
use CGI::Carp qw ( warningsToBrowser fatalsToBrowser );
my $q = CGI -> new;
print $q -> header();
$input = 'abc"abc';
(my $output = $input) =~ s/"/"/g;
print "input = $input\n";
print "output = $output\n";
However, the $output is not changed. How can I get this right?
You should use a module suitable for the purpose, such as HTML::Entities:
use strict;
use warnings;
use HTML::Entities;
my $input = 'abc"abc';
print encode_entities($input);
Output:
abc"abc
In your code, the variable $input is not changed because you are using parentheses to avoid it.
(my $output = $input) =~ s/"/"/g;
This will enforce the assignment to happen first, overruling precedence. Then the regex substitution is applied to $output. When I run your code, I get the expected output:
input = abc"abc
output = abc"abc
If you do not get this output, I expect the quotes in your string is something different than you think.

A Perl Program Which divides a String by spaces between them?

I want my program to divide the string by the spaces between them
$string = "hello how are you";
The output should look like that:
hello
how
are
you
You can do this is a few different ways.
use strict;
use warnings;
my $string = "hello how are you";
my #first = $string =~ /\S+/g; # regex capture non-whitespace
my #second = split ' ', $string; # split on whitespace
my $third = $string;
$third =~ tr/ /\n/; # copy string, substitute space for newline
# $third =~ s/ /\n/g; # same thing, but with s///
The first two creates arrays with the individual words, the last creates a different single string. If all you want is something to print, the last will suffice. To print an array do something like:
print "$_\n" for #first;
Notes:
Normally, regex capture requires parentheses /(\S+)/, but when the /g modifier is used, and parentheses are omitted, the entire match is returned.
When using capture this way, you need to assure list context on the assignment. If the left hand parameter is a scalar, you would force list context with parentheses: my ($var) = ...
I think like simple....
$string = "hello how are you";
print $_, "\n" for split ' ', $string;
#Array = split(" ",$string); then the #Array contain the answer
You need a split for dividing the string by spaces like
use strict;
my $string = "hello how are you";
my #substr = split(' ', $string); # split the string by space
{
local $, = "\n"; # setting the output field operator for printing the values in each line
print #substr;
}
Output:
hello
how
are
you
Split with regexp to account for extra spaces if any:
my $string = "hello how are you";
my #words = split /\s+/, $string; ## account for extra spaces if any
print join "\n", #words

how can I remove \r \n and \ from a string in perl

I need to remove every \r \n and \ in that order from a big $string, how can I accomplish that?
Example string:
$string = '\/9jAAMAAAAB\r\nAAEAAABAAAD\/2'
need it to look like this:
$string = '/9jAAMAAAABAAEAAABAAAD/2'
#!/usr/bin/perl
$string = "something\\r\\n\\";
$string =~ s/(\\r)|(\\n)|(\\)//g;
print $string;
=> something
Here's another option:
use strict;
use warnings;
my $string = '\/9jAAMAAAAB\r\nAAEAAABAAAD\/2';
$string =~ s!\\[rn]?!!g;
print $string;
Output:
/9jAAMAAAABAAEAAABAAAD/2
Here is one way to do it:
$new_string = $string =~ s/\\|\R//g;
print "$new_string";

Perl LWP::Simple File.txt in Array not spaces

The file does not have spaces and do i need to keep every word in the corresponding array,
content in var, the file is more large, but this is ok.
my $file = "http://www.ausa.com.ar/autopista/carteleria/plano/mime.txt";
&VPM4362=008000&VPM4381=FFFFFF&VPM4372=FFFFFF&VPM4391=008000&VPM4382=FFFF00&VPM4392=FF0000&VPM4182=FFFFFF&VPM4181=FFFF00&VPM4402=FFFFFF&VPM4401=FFFF00&VPM4412=008000&VPM4411=FF0000&VPM4422=FFFFFF&VPM4421=FFFFFF&VPM4322=FFFF00&CPMV001_1_Ico=112&CPMV001_1_1=AHORRE 15%&CPMV001_1_2=ADHIERASE AUPASS&CPMV001_1_3=AUPASS.COM.AR&CPMV002_1_Ico=0&CPMV002_1_1=ATENCION&CPMV002_1_2=RADARES&CPMV002_1_3=OPERANDO&CPMV003_1_Ico=0&CPMV003_1_1=ATENCION&CPMV003_1_2=RADARES&CPMV003_1_3=OPERANDO&CPMV004_1_Ico=255&CPMV004_1_1= &CPMV004_1_2=&CPMV004_1_3=&CPMV05 _1_Ico=0&CPMV05 _1_1=ATENCION&CPMV05 _1_2=RADARES&CPMV05 _1_3=OPERANDO&CPMV006_1_Ico=0&CPMV006_1_1=ATENCION&CPMV006_1_2=RADARES&CPMV006_1_3=OPERANDO&CPMV007_1_Ico=0&CPMV007_1_1=ATENCION&CPMV007_1_2=RADARES&CPMV007_1_3=OPERANDO&CPMV08 _1_Ico=0&CPMV08 _1_1=ATENCION&CPMV08
the code.
#!/bash/perl .T
use strict;
use warnings;
use LWP::Simple;
my $file = "http://www.ausa.com.ar/autopista/carteleria/plano/mime.txt";
my $mime = get($file);
my #new;
foreach my $line ($mime) {
$line =~ s/&/ /g;
push(#new, $line);
}
print "$new[0]\n";
Try this way but when I start the array is equal to (all together)
the output I need
print "$new[1]\n";
VPM4381=FFFFFF
You don't want to substitute on &, you want to split on &.
#new = split /&/, $line;