perl assign string on multiple lines - perl

I'd like to be able to assign the concatenation of multiple strings to a variable.
I'm looking for something like this:
$variable = 123
$string = "hello" +
"this is a " +
$variable +
"string";
Is it possible to do something along these lines in perl?

+ does addition. . does concatenation.
my $variable = 123;
my $string = "hello" .
"this is a " .
$variable .
"string";

From perlop #Additive Operators:
Additive Operators
Binary + returns the sum of two numbers.
Binary - returns the difference of two numbers.
Binary . concatenates two strings.
Therefore, for string concatenation you need:
$string = "hello" .
"this is a " .
$variable .
"string";

Related

Can a function be used in a equation

Is there a way to call a function when using an equation within Powershell.
I am trying to something like the following however the last line returns an error You must provide a value expression....
function quote($str) {
return """" + $str + """";
};
$a= "abc: " + quote('hi'); # <-- Doesn't Work
I realize I could assign the quote to an intermediate variable and then do the concatenation ($q=quote('hi'); $a="abc: " + q$) however I am hoping there is a simpler syntax.
Is this what you mean:
function quote($str) {
return """" + $str + """";
};
$a= "abc: " + $(quote('hi'));
# edit: as per Joey's comment, this will also work:
$a= "abc: " + (quote('hi'));
Edit
Re-written using PowerShell syntax:
# Function name is verb-noun, from approved verbs
# https://msdn.microsoft.com/en-us/library/ms714428(v=vs.85).aspx
Function Add-Quote{
# parameters this function takes
param([string]$str)
# No need for return and semi colon.
# I tend to use return as it makes my code reading easier
"""" + $str + """"
}
$a = "abc: " + (Add-Quote -str 'hi')
You could use the format operator -f to insert the string.
function quote {
param($str)
"`"$str`""
}
$a = 'abc: {0}' -f (quote 'hi')

how to remove special character "," from a string using perl

hi i have some data like below
S_ METHOD m0 : 47|8#0- (1,0) [0|0] ""
S_ CTRL m1 : 15|8#0- (0.01,-200) [0|0] ""
from above 2 lines i am trying to extract that are in curve brackets () i have written a perl script
my #temp_signal = split(":",$line);
my #signal= split(" ",#temp_signal[0]);
my #Factor_temp1 = split (" ",#temp_signal[1]);
my #factor_temp = split ('\(',#Factor_temp1[1]);
my #factor = chop(#factor_temp);
my #offset = split (",",#factor_temp);
print OUTFILE1 "#offset[0]\n";
print OUTFILE1 "$signal[1]\n";
but when am trying to print #offset[1] & #offset[0] its printing some other value which is not even exist in the line how can i get the values as
1 0
0.01 -200
You can use a regular expression match to extract what's inside parentheses separated by a comma:
if ( my #numbers = $line =~ /\((.*),(.*)\)/) {
print "$numbers[0] $numbers[1]\n";
}

Exact pattern match using perl index() function

I am trying to use the index() function and I want to find the position of a word inside a string, only when it is an exact match. For example:
My string is STRING="CATALOG SCATTER CAT CATHARSIS"
And my search string is KEY=CAT
I want to say something like index($STRING, $KEY) and check match for CAT, and not CATALOG. How do I accomplish this? The documentation says
The index function searches for one string within another, but without the wildcard-like behavior of a full regular-expression pattern match.
which makes me think that it may not be that straight-forward, but my perl skills are limited :). Is it possible to do what I am trying to do?
Hopefully, I was able to articulate my question well. Thanks in advance for your help!
How about:
my $str = "CATALOG SCATTER CAT CATHARSIS";
my $key = "CAT";
if ($str =~ /\b$key\b/) {
say "match at char ",$-[0];;
} else {
say "no match";
}
output:
match at char 16
You need to learn about Regular Expressions in Perl. Perl didn't invent Regular Expressions, but tremendously expanded upon the concept. In fact, many other programming languages talk specifically about using Perl Regular Expressions.
A regular expression matches a specific word pattern. For example, /cat/ matches the sequence cat in a string.
if ( $string =~ /cat/ ) {
print "String contains the letters 'cat' in a row\n";
}
In many ways, this does the same thing as:
my $location = index ( $string, "cat" );
if ( $location =! -1 ) { # index returns -1 when substring isn't found
print "String contains the letters 'cat' in a row\n";
}
But, both of these would match:
"Don't let the cat out of the bag"
"The Sears catalog arrived in the mail"
You don't want to match the last. So, you could do this:
my $location = index $string, " cat ";
Now, index $string, " cat " won't match the word catalog. Case closed! Or is it? What about:
"cat and dog it doth rain."
Maybe you could check and say things are okay if a sentence starts with "cat":
if ( (index ($string, " cat ") != -1) or (index ($string, "cat") = 0) ) {
print "String contains the letters 'cat' in a row\n";
}
But, what about these?
"The word CAT in all uppercase"
"Stupid cat"
"Cat! Here Cat! Common Cat!": Punctuation after the word "cat"
"Don't let the 'cat' out of the 'bag'": Quotation Marks around "cat"
It could take dozens of lines to specify each and every one of these conditions.
However:
if ( $string =~ /\bcat\b/i ) {
print "String contains the word 'cat' in it\n";
}
Specifies each and every one -- and then some. The \b says this is a word boundary. This could be a space, a tab, a quote, the beginning or ending of a line. Thus /\bcat\b/ specifies that this should be the word cat and not catalog. The i on the end tells your regular expression to ignore case when matching, so you'll find Cat, cat, CAT, cAt, and all other possible combinations.
In fact, Perl's regular expressions is what made Perl such a popular language to begin with.
Fortunately, Perl comes with not one, but two tutorials on Regular Expressions:
perlretut: Perl Regular Expression Tutorial
perlrequick: Perl Regular Expression Quick Start.
Hope this helps.
That's (partial) solution of this problem with index:
use warnings;
use strict;
my $test = 'CATALOG SCATTER CAT CATHARSIS';
my $key = 'CAT';
my $k_length = length $key;
my $s_length = (length $test) - $k_length;
my $pos = -1;
while (($pos = index $test, $key, $pos + 1) > -1) {
if ($pos > 0) {
my $prev_char = substr $test, $pos - 1, 1;
### print "Previous character: '$prev_char'\n";
next if $prev_char ge 'A' && $prev_char le 'Z'
|| $prev_char ge 'a' && $prev_char le 'z';
}
if ($pos < $s_length) {
my $next_char = substr $test, $pos + $k_length, 1;
### print "Next character: '$next_char'\n";
next if $next_char ge 'A' && $next_char le 'Z'
|| $next_char ge 'a' && $next_char le 'z';
}
print "Word '$key' found at " . $pos + 1 . "th position.\n";
}
As you see, it's kinda wordy, because it uses basic Perl string functions - index and substr - only. Checking whether the substring found is indeed a word is done via checking its next and previous characters (if they exist): if they belong to either A-Z or a-z range, it's not a word.
You can simplify it a bit by trying to lowercase these characters (with lc), then check against the single character range only:
my $lc_prev_char = lc( substr $test, $pos - 1, 1 );
next if $lc_prev_char ge 'a' && $lc_prev_char le 'z';
... but then again, it's quite a minor improvement (if improvement at all).
Now consider this:
my $test = 'CATALOG SCATTER CAT CATHARSIS CAT';
my $key = 'CAT';
while ($test =~ /(?<![A-Za-z])$key(?![A-Za-z])/g) {
print "Word '$key' found at " . ($-[0] + 1) . "th position.\n";
}
... and that's it! The pattern literally tests the string given ($test) for the substring given ($key) not being either preceded with or followed by the symbol of A-Za-z range, and supporting Perl regex magic (this variable, in particular) makes it easy to get the starting position of such substring.
The bottom line: use regexes to do the regexes' work.
Regular expressions allow for the search to contain word boundaries as well as distinct characters. While
my $string = "CATALOG SCATTER CAT CATHARSIS";
index($string, 'CAT');
will return zero or greater if $string contains the characters CAT, a regular expression like
$string =~ /\bCAT\b/;
will return false as $string doesn't contain CAT preceded and followed by a word boundary. (A word boundary is either the beginning or end of the string, or between an word character and a non-word character. A word character is any alphanumeric character or an underscore.)
use \E value.
so :
#!usr/bin/perl
my $string ="Little Tony";
my $check = "Ton";
if($string =~ m/$check\E/g)
{
print "match";
}
else
{
die("No Match");
}

encode special character in html entities in perl

I have a string where special characters like ! or " or & or # or #, ... can appear. How can I convert in the string
str = " Hello "XYZ" this 'is' a test & so *n #."
automatically every special characters with their html entities, so that I get this:
str = " Hello &quot ;XYZ&quot ; this &#39 ;is&#39 ; a test &amp ; so on #"
I tried
$str=HTML::Entities::encode_entities($str);
but it does a partial work the # is not transformed in &#64 ;
SOLUTION:
1) with your help (Quentin and vol7ron) I came up with this solution(1)
$HTML::Entities::char2entity{'#'} = '#';
$HTML::Entities::char2entity{'!'} = '!';
$HTML::Entities::char2entity{'#'} = '#';
$HTML::Entities::char2entity{'%'} = '%';
$HTML::Entities::char2entity{'.'} = '.';
$HTML::Entities::char2entity{'*'} = '*';
$str=HTML::Entities::encode_entities($str, q{#"%'.&#*$^!});
2) and I found a shorter(better) solution(2) found it here:
$str=HTML::Entities::encode_entities($str, '\W');
the '\W' does the job
#von7ron with solution(1) you will need to specify the characters you want to translate as Quentin mentioned earlier even if they are on the translation table.
# isn't transformed because it isn't considered to be a "special character". It can be represented in ASCII and has no significant meaning in HTML.
You can expand the range of characters that are converted with the second argument to the function you are using, as described in the documentation.
You can manually add a character to the translation table (char2entity hash).
$HTML::Entities::char2entity{'#'} = '#';
my $str = q{ Hello "XYZ" this 'is' a test & so on #};
my $encoded = HTML::Entities::encode_entities( $str, q{<>&"'#} );
The above adds #, which will be translated to #.
You then need to specify the characters you want to translate, if you don't it uses <>&", so I added both # and '. Notice, I didn't have to add the ' to the translation table, because it's already there by default.
You don't need to add ASCII characters (0-255) to the char2entity hash, since the module will do it automatically.
Note: Setting the char2entity for #, was done as an example. The module automatically sets numerical entities for ASCII characters (0-255) that weren't found. You'd have to use it for unicode characters, though.
Cheap, dirty, and ugly, but works:
my %translations;
$translations{'"'} = '&quot ;';
$translations{'\''} = '&#39 ;';
etc...
sub transform()
{
my $str = shift;
foreach my $character (keys(%translations))
{
$str =~ s/$character/$translations{$character}/g;
}
return $str;
}

What's the difference between single and double quotes in Perl?

In Perl, what is the difference between ' and " ?
For example, I have 2 variables like below:
$var1 = '\(';
$var2 = "\(";
$res1 = ($matchStr =~ m/$var1/);
$res2 = ($matchStr =~ m/$var2/);
The $res2 statement complains that Unmatched ( before HERE mark in regex m.
Double quotes use variable expansion. Single quotes don't
In a double quoted string you need to escape certain characters to stop them being interpreted differently. In a single quoted string you don't (except for a backslash if it is the final character in the string)
my $var1 = 'Hello';
my $var2 = "$var1";
my $var3 = '$var1';
print $var2;
print "\n";
print $var3;
print "\n";
This will output
Hello
$var1
Perl Monks has a pretty good explanation of this here
' will not resolve variables and escapes
" will resolve variables, and escape characters.
If you want to store your \ character in the string in $var2, use "\\("
Double quotation marks interpret, and single quotation do not
If you are going to create regex strings you should really be using the qr// quote-like operator:
my $matchStr = "(";
my $var1 = qr/\(/;
my $res1 = ($matchStr =~ m/$var1/);
It creates a compiled regex that is much faster than just using a variable containing string. It also will return a string if not used in a regex context, so you can say things like
print "$var1\n"; #prints (?-xism:\()
Perl takes the single-quoted strings 'as is' and interpolates the double-quoted strings. Interpolate means, that it substitutes variables with variable values, and also understands escaped characters. So, your "\(" is interpreted as '(', and your regexp becomes m/(/, this is why Perl complains.
"" Supports variable interpolation and escaping. so inside "\(" \ escapes (
Where as ' ' does not support either. So '\(' is literally \(