What is that meaning of $testModule =~ s#/#::#ig; in Perl? - regex

I am a newbie of perl and I'm reading some perl codes, I find one line below I could't understand, can anyone tell what is the meaning of
s#/#::#ig
I know =~ is try to match some regular expression. usually I would see code like s/<regular express>//gi, so I was a little confused of the following code. can anyone help to elaborate?
$testModule =~ s#/#::#ig;

You can use lots of different characters as regex delimiters.
This one is using # instead of / so it can use / as data inside the regex without escaping it.
It's equivalent to:
$testModule =~ s/\//::/ig;
See quote and quote-like operators in the Perl documentation for more details.

Related

What matches this regex in perl: qr!$line!;

In one source code I found this regex:
my $var = qr!$my_string!;
I simply can't figure out what this matches. I also searched online, the explanation to qr is quite simple.
Can someone explain it in an human language, please? :)
Most quote-like operators can take nearly anything for delimiters.† The qr is no exception, here using ! as delimiter. It also evaluates ("interpolates") variables that are quoted. So that line of code builds a regex pattern using what is in $my_string variable. This pattern is presumably used later in code in regex expressions. This is normal use.
A complete example:
use warnings;
use strict;
use feature 'say';
my $str = q(hey);
my $re = qr!$str!;
my $tgt = q(A_hey_C);
$tgt =~ s/$re/B/;
say $tgt; #--> A_B_C
The purpose of qr is specifically to construct a regex pattern so one would expect that the $str above ($my_string in the question), or the pattern in qr, would contain regex-specific patterns, perhaps along with other variables assembled in the program. The $str above with just a plain string can nicely be used directly in a regex, so this isn't a realistic example.
† See
What are the legal delimiters for Perl 5's pick-your-own-quotes operators?

perl regular expressions substitue

I'm new to perl and I found this expressions bit difficult to understand
$a =~ s/\'/\'\"\'\"\'/g
Can someone help me understand what this piece of code does?
It is not clear which part of it is a problem. Here is a brief mention of each.
The expression $str =~ s/pattern/replacement/ is a regular expression, replacing the part of string $str that is matched by the "pattern", by the "replacement". With /g at the end it does so for all instances of the "pattern" found in the string. There is far, far more to it -- see the tutorial, a quick start, the reference, and full information in perlre and perlop.
Some characters have a special meaning, in particular when used in the "pattern". A common set is .^$*+?()[{\|, but this depends on the flavor of regex. Also, whatever is used as a delimiter (commonly /) has to be escaped as well. See documentation and for example this post. If you want to use any one of those characters as a literal character to be found in the string, they have to be escaped by the backslash. (Also see about escaped sequences.) In your example, the ' is escaped, and so are the characters used as the replacement.
The thing is, these in fact don't need to be escaped. So this works
use strict;
use warnings;
my $str = "a'b'c";
$str =~ s/'/'"'/g;
print "$str\n";
It prints the desired a'"'b'"'c. Note that you still may escape them and it will work. One situation where ' is indeed very special is in a one liner, where it delimits the whole piece of code to submit to Perl via shell, to be run. (However, merely escaping it there does not work.) Altogether, the expression you show does the replacement just as in the answer by Jens, but with a twist that is not needed.
A note on a related feature: you can use nearly anything for delimiters, not necessarily just /. So this |patt|repl| is fine, and nicely even this is: {patt}{repl} (unless they are used inside). This is sometimes extremely handy, improving readability a lot. For one thing, then you don't have to escape the / itself inside the regex.
I hope this helps a little.
All the \ in that are useless (but harmless), so it is equivalent to s/'/'"'"'/g. It replaces every ' with '"'"' in the string.
This is often used for shell quoting. See for example https://stackoverflow.com/a/24869016/17389
This peace of Code replace every singe Quote with '"'"'
Can be simplified by removing the needless back slashes
$a =~ s/'/"'"'/g
Every ' will we replaced with "'"'

Backtick Character ` in Perl Regex Meaning

I have inherited a Perl codebase that uses regex to parse an XML file. Not optimal, I know. I have lines of code like:
$title =~ s`<(.*?)>``g;
and
$content =~ s`__DOUBLEFIG__`${fig_html}`;
The standard Perl find and replace takes the form of
s/foo/bar/g;
What does
s`foo`bar`g;
do?
Those are alternative ways of delimiting the regex. Whomever wrote that code chose to use something else for personal reasons or, possibly, for code readability. Often, if patterns are often going to involve /, something else will be chosen to avoid having to escape the slash character in the regex.
This answer provides more information.

Perl Extended Regular Expressions - match with multiple question marks inside

I have got a weird thing to solve in perl using regular expressions.
Consider the strings -
abcdef000000123
blaDeF002500456
wefdEF120045423
All of these strings are matching with the below regular expression when I tried in C with pcre library support :
???[dD][eE][fF][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]
But I'm unable to achieve the same in perl code. I'm getting some weird errors.
Please help with the piece of perl code with which these two things match.
Thanks in advance...
? is called quantifier that makes preceding pattern or group an optional match. Independently ? doesn't make any sense in regex and you are getting an error like: Quantifier follows nothing in regex.
Following regex should work for you in perl:
...[dD][eE][fF][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]
OR even more concise regex:
.{3}[dD][eE][fF][0-9]{9}
Each dot means match any character.
PS: You probably are getting confused by shell's glob vs regex.
That looks more like a file system regex than a PCRE. In Perl, the ? is a quantifier, not a wild card. You may want to replace them with . to get the same results in anything Perl compatible.
I might use ...[dD][eE][fF][0-9]{9} or even replace the [0-9] with \d.
qr/[A-z]{3}def[0-9]{9}/i
should be the Perl Regex object used to validate the mentioned strings.
Regards

Regex to replace all ocurrences of a given character, ONLY after a given match

For the sake of simplicity, let's say that we have input strings with this format:
*text1*|*text2*
So, I want to leave text1 alone, and remove all spaces in text2.
This could be easy if we didn't have text1, a simple search and replace like this one would do:
%s/\s//g
but in this context I don't know what to do.
I tried with something like:
%s/\(.*|\S*\).\(.*\)/\1\2/g
which works, but removing only the first character, I mean, this should be run on the same line one time for each offending space.
So, a preferred restriction, is to solve this with only one search and replace. And, although I used Vim syntax, use the regular expression flavor you're most comfortable with to answer, I mean, maybe you need some functionality only offered by Perl.
Edit:
My solution for Vim:
%s:\(|.*\)\#<=\s::g
One way, in perl:
s/(^.*\||(?=\s))\s*/$1/g
Certainly much greater efficiency is possible if you allow more than just one search and replace.
So you have a string with one pipe (|) in it, and you want to replace only those spaces that don't precede the pipe?
s/\s+(?![^|]*\|)//g
You might try embedding Perl code in a regular expression (using the (?{...}) syntax), which is, however, rather an experimental feature and might not work or even be available in your scenario.
This
s/(.*?\|)(.*)(?{ $x = $2; $x =~ s:\s::g })/$1$x/
should theoretically work, but I got an "Out of memory!" failure, which can be fixed by replacing '\s' with a space:
s/(.*?\|)(.*)(?{ $x = $2; $x =~ s: ::g })/$1$x/