Join function not working - perl

Below script break the sequence at every 'E' and subsequently an 'E' is added on to each fragment. But I'm not getting 'E' attached to my last element, Why?
use strict;
use warnings;
my $s = 'ABCDEABCDEABCDEABCDEABCDE';
my #a = split /E(?!P)/, $s;
my $result = join "E,", #a;
my #final = split /,/, $result;
print "#final\n";

A join joins its first argument between successive elements. If you want to add the final "E", you could simply do:
$s = 'ABCDEABCDEABCDEABCDEABCDE';
#a = split(/E(?!P)/, $s);
print join ("E ", #a), "E\n";

See the documentation of split:
By default, empty leading fields are preserved, and empty trailing ones are deleted.

Related

Why function does not receive arguments?

I have next code:
my $str = '';
new( (split ',', $str )[0] )
Here I split my $str and asks exactly one element from result list
But when check incoming data at #_ I see zero elements
Why function does not receive arguments?
I expect one element
Here is some code that tests what you say in your question.
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
sub new {
say 'new() received ' . #_ . ' argument(s).';
say "The first argument was '$_[0].'" if #_;
}
my $str = 'one,two,three';
new( (split ',', $str )[0] );
When I run it, I get the following output:
$ perl split_test
new() received 1 argument(s).
The first argument was 'one.'
This seems to be working as expected. So it seems likely that your problem lies in parts of the code that you haven't shared with us.
It seems I found the answer.
Problem was because of special case when I slice empty list.
This special case is useful at while condition:
while ( ($home, $user) = (getpwent)[7,0] ) {
printf "%-8s %s\n", $user, $home;
}
Here is documentation for this
#a = ()[0,1]; # #a has no elements
#b = (#a)[0,1]; # #b has no elements
#c = (sub{}->())[0,1]; # #c has no elements
#d = ('a','b')[0,1]; # #d has two elements
#e = (#d)[0,1,8,9]; # #e has four elements
#f = (#d)[8,9]; # #f has two elements

How to copy the contents of array into a single variable in Perl?

I have a data in an array as below. I want to copy all the content in a single variable. How can I do this ?
IFLADK
FJ
FAILED
FNKS
FKJ
FAILED
You could assign a reference to the array
my $scalar = \#array;
… or join all the strings in the array together
my $scalar = join "\n", #array;
With reference to previous question How to read n lines above the matched string in perl? Storing multiple hits in an array:
while (<$fh>) {
push #array, $_;
shift #array if #array > 4;
if (/script/) {
print #array;
push #found, join "", #array; # <----- this line
}
}
You could just use a scalar, e.g. $found = join "", #array, but then you would only store the last match in the loop.
Suppose the loop is finished, and now you have all the matches in array #found. If you want them in a scalar, just join again:
my $found = join "", #found;
Or you can just add them all at once in the loop:
$found .= join "", #array;
It all depends on what you intend to do with the data. Having the data in a scalar is rarely more beneficial than having it in an array. For example, if you are going to print it, there is no difference, as print $found is equivalent to print #found, because print takes a list of arguments.
If your intent is to interpolate the matches into a string:
print "Found matches: $found";
print "Found matches: ", #found;
$whole = join(' ', #lines)
But if you're reading the text from a file, it's easier to just read it all in one chunk, by (locally) undefining the record delimiter:
local $/ = undef;
$whole = <FILE>
Depends on what you are trying to do, but if you are wanting to package up an array into a scalar so that it can be retrieved later, then you might want Storable.
use Storable;
my #array = qw{foo bar baz};
my $stored_array = freeze \#array;
...
my #retrieved_array = #{ thaw($stored_array) };
Then again it could be that your needs may be served by just storing a reference to the array.
my #array = qw{foo bar baz};
my $stored_array = \#array;
...
my #retrieved_array = #$stored_array;

In perl, how to split a string in this desired way?

I have a string str a\tb\tc\td\te
I want the 1st field value a to go in a variable, then 2nd field value b to go in other variable, then both c\td to go in 3rd variable and last field value e to go in one variable.
If I do
my ($a,$b,$c,$d) = split(/\t/,$_,4);
$c will acquire only c and $d will acquire d\te
I can do:
my ($a,$b,$c) = split(/\t/,$_,3);
Then c will get c\td\te
and I can somehow (How?) get rid of last value and get it in $d
How to achieve this?
split is good when you're keeping the order. If you're breaking the ordering like this you have a bit of a problem. You have two choices:
split according to \t and then join the ones you want.
be explicit.
an example of the first choice is:
my ($a,$b,$c1, $c2, $d) = split /\t/, $_;
my $c = "$c1\t$c2";
an example of the second choice is:
my ($a, $b, $c, $d) = (/(.*?)\t(.*?)\t(.*?\t.*?)\t(.*?)/;
each set of parentheses captures what you want exactly. Using the non-greedy modifier (?) after the * ensures that the parentheses won't capture \t.
Edit: if the intent is to have an arbitrary number of variables, you're best off using an array:
my #x = split /\t/, $_;
my $a = $x[0];
my $b = $x[1];
my $c = join "\t", #x[2..($#x-1)];
my $d = $x[-1];
You can use a regex with a negative look-ahead assertion, e.g.:
my #fields = split /\t(?!d)/, $string;

Reformulate a string query in perl

How do i reformulate a string in perl?
For example consider the string "Where is the Louvre located?"
How can i generate strings like the following:
"the is Louvre located"
"the Louvre is located"
"the Louvre located is"
These are being used as queries to do a web search.
I was trying to do something like this:
Get rid of punctuations and split the sentence into words.
my #words = split / /, $_[0];
I don't need the first word in the string, so getting rid of it.
shift(#words);
And then i need move the next word through out the array - not sure how to do this!!
Finally convert the array of words back to a string.
How can I generate all permutations of an array in Perl?
Then use join to glue each permutation array back together into a single string.
Somewhat more verbose example:
use strict;
use warnings;
use Data::Dumper;
my $str = "Where is the Louvre located?";
# split into words and remove the punctuation
my #words = map {s/\W+//; $_} split / /, $str;
# remove the first two words while storing the second
my $moving = splice #words, 0 ,2;
# generate the variations
my #variants;
foreach my $position (0 .. $#words) {
my #temp = #words;
splice #temp, $position, 0, $moving;
push #variants, \#temp;
}
print Dumper(\#variants);
my #head;
my ($x, #tail) = #words;
while (#tail) {
push #head, shift #tail;
print join " ", #head, $x, #tail;
};
Or you can just "bubble" $x through the array: $words[$n-1] and words[$n]
foreach $n (1..#words-1) {
($words[$n-1, $words[$n]) = ($words[$n], $words[$n-1]);
print join " ", #words, "\n";
};

Appending a prefix when using join in Perl

I have an array of strings that I would like to use the join function on. However, I would like to prefix each string with the same string. Can I do this in one line as opposed to iterating through the array first and changing each value before using join?
Actually it's a lil bit trickier. The prefix is not part of the join separator. Meaning if you used a prefix like "num-" on an array of (1,2,3,4,5), you will want to get this result: num-1,num-2,num-3,num-4,num-5
This code:
my #tmp = qw(1 2 3 4 5);
my $prefix = 'num-';
print join "\n", map { $prefix . $_ } #tmp;
gives:
num-1
num-2
num-3
num-4
num-5
Just make the prefix part of the join:
my #array = qw(a b c d);
my $sep = ",";
my $prefix = "PREFIX-";
my $str = $prefix . join("$sep$prefix", #array);
You could also use map to do the prefixing if you prefer:
my $str = join($sep, map "$prefix$_", #array);