Wanted clarification [duplicate] - regex

This question already has an answer here:
Reference - What does this regex mean?
(1 answer)
Closed 7 years ago.
I am trying to understand some code which is already written..
I am not able to understand
my $l = $0; $l =~ s-/[^/]+/[^/]+$-/lib/perl-;
what is assigned to $0 ?
what is - (Hyphen) operator in the expression ?
whay $- is used in the expression?
Please explain the ablove 3Qs.
BEGIN {
# figure out our general library path
my $p;
my $l = $0; $l =~ s-/[^/]+/[^/]+$-/lib/perl-;
push #INC,$l;
# add some platform components, based on files
push #INC,"$l/sunos" if ( grep /solaris/,#INC );
push #INC,"$l/csw" if ( grep /csw/,#INC );
push #INC,"$l/i386" if ( grep /i386/,#INC );
push #INC,"$l/x86_64" if ( grep /x86_64/,#INC );
}

You can find various Perl special variables in perlvar. $0 is explained there.
As mentioned in perlop, the substitution operator s/REGEX/REPLACEMENT/ can be written with different delimiters, e.g. dashes. It's handy when the regex or replacement contain slashes, as is the case here. Using paired delimiters might be more readable:
s{/[^/]+/[^/]+$}{/lib/perl}
or, using /x:
s{ / [^/]+ / [^/]+ $ }{/lib/perl}x

Related

Regex to match end of the string and capture the part before end of the string perl [duplicate]

This question already has an answer here:
Reference - What does this regex mean?
(1 answer)
Closed 4 years ago.
I'm trying to match any string with the regex that ends with /? and extract the string before /?
Below is my code:
$input = "boringinterestingboring/?";
if($input =~ /(.*)\/?$/) {
print "$1\n";
}
else {
print "not matched";
}
I'm trying to capture "boringinterestingboring" using (.*) but it's not doing that, instead it captures the whole string.
How should i get only the string before /?.
Please help.
To match everything up to, but not including, a /?:
.*(?=/\?)
If you’re not sure about escaping, you can use a character class to do the escaping for you:
.*(?=/[?])
It may seem duplicate, but as the answer of your question,
Your regex need to be:
/(.*)\/\?$/
or
/(.*)(?=\/\?$)/
Example:
$input = "boringinterestingboring/?";
print "Use \$1: $1\n" if($input =~ /(.*)\/\?$/);
print "Use \$1: $1\n" if($input =~ /(.*)(?=\/\?$)/);
print "Use \$&: $&\n" if($input =~ /.*(?=\/\?$)/);
Output:
Use $1: boringinterestingboring
Use $1: boringinterestingboring
Use $&: boringinterestingboring
Different ways, same destination. But either way, you should escape ? too, or put it in [].
Using positive lookahead. The assertion (?=..) will match /? but will not make it part of the capturing group even if it is nested in another group.
$ echo "boringinterestingboring/?" | perl -ne ' ($x)=/(boringinterestingboring(?=\/\?))/ ; print $x '
boringinterestingboring
$
Negative test case. Below prints nothing
$ echo "boringinterestingboring#?" | perl -ne ' ($x)=/(boringinterestingboring(?=\/\?))/ ; print $x '
$

regex for multiple strings

I have two strings that I'm trying to match in a file and return just that line.
The first string will match what I'm looking for always but not completely.
Example:
I might be looking for Matcht in Matchthisstring so I match but not the entire string.
String 1 might come before or after string 2 and it might start with an uppercase or lower case letter.
Example:
I might be looking for actually but have Actually.
But it together and I have things like Matchthisstring.Actually or actually.Matchthisstring or Matchthisstring.someotherjunkIdon'tcareabout.actually any other combinations like that.
I'm having problems using the two search strings together and getting the reggae to work.
Here's an example of some code that works:
my #matches;
while (<$in_fh>) {
#push #matches, $_ if / \Q$wanted\E .* \Q$prefix\E /x;
#push #matches, $_ if / \Q^*(.*)$wanted\s*(.*)\E .* \Q^*(.*)$prefix\s*(.*)\E /x;
push #matches, $_ if / \Q$wanted\E /x;
}
what I really want to work is one of the other options that's commented out. I don't think I'm joining the two searches into one string together properly.
Thanks in advance for the assistance.
Sounds like you want
push #matches, $_ if /\Q$wanted\E/ and /\Q$prefix\E/;
Demo:
$ perl -ne 'use strict; use warnings; use vars qw($wanted $prefix #matches);
> BEGIN { $wanted = "/donate"; $prefix = "lghfound"; }
> push #matches, $_ if /\Q$wanted\E/ and /\Q$prefix\E/; print #matches' <<'HERE'
> http://www.google.com/donate
> http://lghfoundation.com/pages/donate.html
> http://example.com
> HERE
http://lghfoundation.com/pages/donate.html
http://lghfoundation.com/pages/donate.html

Replacing backslashes with two backslashes using regex [duplicate]

This question already has answers here:
Perl regex: replace all backslashes with double-backslashes
(6 answers)
Closed 8 years ago.
How do I replace single backslashes in a string with double backslashes?
I've tried things such as
s/\\(?!\\)/\\\\/g
s/\\/\\\\/g
s/[^//]/\\\\/g
But they all produce multiple backslashes after each other.
So I want:
\test
to be replaced with
\\test
Edit: Sorry I should also mention that the regex is in a loop so I need a regex that only matches the string if there is ONLY ONE backslash. Once there is more than one backslash then the regex should reject the string. Apologies
The most helpful thing to note is to use a different delimiter for the regex, so things don't get jumbled by all the leaning towers:
my $str = '\test';
$str =~ s{\\}{\\\\}g;
print $str;
Outputs:
\\test
Update
Per your revised specification, if you only want to escape a single backslash, and ignore all others, then just use a negative lookahead and lookbehind assertion:
my $str = <<'END_STR';
\one \\two \\\three
END_STR
print $str;
$str =~ s{(?<!\\)\\(?!\\)}{\\\\}g;
print $str;
Outputs:
\one \\two \\\three
\\one \\two \\\three
echo '\replace' | perl -pe 's/\\/\\\\/g'
\\replace
OR with sed
# echo '\replace' | sed 's/\\/\\\\/g'
\\replace

Bash regex matching not working [duplicate]

This question already has answers here:
Bash Regular Expression -- Can't seem to match any of \s \S \d \D \w \W etc
(6 answers)
Closed 5 years ago.
so I have this function
function test(){
local output="CMD[hahahhaa]"
if [[ "$output" =~ "/CMD\[.*?\]/" ]]; then
echo "LOOL"
else
echo "$output"
fi;
}
however executing test in command line would output $output instead of "LOOL" despite the fact that the pattern should be matching $output...
what did I do wrong?
Don't use quotes ""
if [[ "$output" =~ ^CMD\[.*?\]$ ]]; then
The regex operator =~ expects an unquoted regular expression on its RHS and does only a sub-string match unless the anchors ^ (start of input) and $ (end of input) are also used to make it match the whole of the LHS.
Quotations "" override this behaviour and force a simple string match instead i.e. the matcher starts looking for all these characters \[.*?\] literally.

How can I make part of a Perl regular expression optional? [duplicate]

This question already has answers here:
How can I make part of regex optional?
(2 answers)
Closed 4 months ago.
I want match
my #array = ( 'Tree' , 'JoeTree');
foreach (#array ) {
if ( $_ =~ /^(Joe)Tree/gi) {
print "matched $_";
}
}
It matching only JoeTree. It's not matching Tree ?
Try:
if (/^(?:Joe)?Tree/gi)
We've made the Joe part optional.
Also you can change (..) to
(?:...) as you are just grouping.
Also $_ =~ part is redundant as by
default we check in $_
You missed a ?: /^(Joe)?Tree/gi