Regular expression to validate an email in perl - perl

I am new in Perl and trying to catch hold of the scripting language where I come across regular expression to validate a email address. I am sharing the perl script. I am not sure where I am making mistake in it. The \# part is omitted always following which the correct email id is also showing as invalid.
Here is the code :
#!/usrs/bin/perl/
$string = "XYZ#yahoo.com";
if ( $string =~ /([a-zA-Z]+)\#([a-zA-Z]+)\.(com|net|org)/)
{
print "TRUE";
print $string;
}
else
{
print "FALSE";
print $string;
}
Thanks for your help.

The regex for validating an email address is included in the source code for Email::Valid. I've copied it below:
$RFC822PAT = <<'EOF';
[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\
xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xf
f\n\015()]*)*\)[\040\t]*)*(?:(?:[^(\040)<>#,;:".\\\[\]\000-\037\x80-\x
ff]+(?![^(\040)<>#,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n\015
"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\040\t]*(?:\([^\\\x80-\
xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80
-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*
)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\
\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\
x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>#,;:".\\\[\]\000-\037\x8
0-\xff]+(?![^(\040)<>#,;:".\\\[\]\000-\037\x80-\xff])|"[^\\\x80-\xff\n
\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[\040\t]*(?:\([^\\\x
80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^
\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040
\t]*)*)*#[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([
^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\
\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<>#,;:".\\\[\]\000-\037\
x80-\xff]+(?![^(\040)<>#,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-
\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()
]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\
x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\04
0\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\
n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\
015()]*)*\)[\040\t]*)*(?:[^(\040)<>#,;:".\\\[\]\000-\037\x80-\xff]+(?!
[^(\040)<>#,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\
]]|\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\
x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\01
5()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*|(?:[^(\040)<>#,;:".
\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>#,;:".\\\[\]\000-\037\x80-\xff]
)|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[^
()<>#,;:".\\\[\]\x80-\xff\000-\010\012-\037]*(?:(?:\([^\\\x80-\xff\n\0
15()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][
^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)|"[^\\\x80-\xff\
n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015"]*)*")[^()<>#,;:".\\\[\]\
x80-\xff\000-\010\012-\037]*)*<[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?
:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-
\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:#[\040\t]*
(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015
()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()
]*)*\)[\040\t]*)*(?:[^(\040)<>#,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\0
40)<>#,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\
[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\
xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*
)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80
-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x
80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t
]*)*(?:[^(\040)<>#,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>#,;:".\\
\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])
*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x
80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80
-\xff\n\015()]*)*\)[\040\t]*)*)*(?:,[\040\t]*(?:\([^\\\x80-\xff\n\015(
)]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\
\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*#[\040\t
]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\0
15()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015
()]*)*\)[\040\t]*)*(?:[^(\040)<>#,;:".\\\[\]\000-\037\x80-\xff]+(?![^(
\040)<>#,;:".\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|
\\[^\x80-\xff])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80
-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()
]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x
80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^
\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040
\t]*)*(?:[^(\040)<>#,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>#,;:".
\\\[\]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff
])*\])[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\
\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x
80-\xff\n\015()]*)*\)[\040\t]*)*)*)*:[\040\t]*(?:\([^\\\x80-\xff\n\015
()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\
\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)?(?:[^
(\040)<>#,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>#,;:".\\\[\]\000-
\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\xff\
n\015"]*)*")[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|
\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))
[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff
\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\x
ff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(
?:[^(\040)<>#,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>#,;:".\\\[\]\
000-\037\x80-\xff])|"[^\\\x80-\xff\n\015"]*(?:\\[^\x80-\xff][^\\\x80-\
xff\n\015"]*)*")[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\x
ff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)
*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*)*#[\040\t]*(?:\([^\\\x80-\x
ff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-
\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)
*(?:[^(\040)<>#,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>#,;:".\\\[\
]\000-\037\x80-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\]
)[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-
\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\x
ff\n\015()]*)*\)[\040\t]*)*(?:\.[\040\t]*(?:\([^\\\x80-\xff\n\015()]*(
?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]*(?:\\[^\x80-\xff][^\\\x80
-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)*\)[\040\t]*)*(?:[^(\040)<
>#,;:".\\\[\]\000-\037\x80-\xff]+(?![^(\040)<>#,;:".\\\[\]\000-\037\x8
0-\xff])|\[(?:[^\\\x80-\xff\n\015\[\]]|\\[^\x80-\xff])*\])[\040\t]*(?:
\([^\\\x80-\xff\n\015()]*(?:(?:\\[^\x80-\xff]|\([^\\\x80-\xff\n\015()]
*(?:\\[^\x80-\xff][^\\\x80-\xff\n\015()]*)*\))[^\\\x80-\xff\n\015()]*)
*\)[\040\t]*)*)*>)
EOF
But your actual problem is this line:
$string = "XYZ#yahoo.com";
The #yahoo looks like an array variable to Perl, and and you don't have an array called #yahoo it gets replaced with an empty string. Try printing the value of $string to see what you get.
The solution is either to use single quotes (so the array variable isn't expanded):
$string = 'XYZ#yahoo.com';
Or to escape the # with a \:
$string = "XYZ\#yahoo.com";
Alway add use strict and use warnings to your Perl programs. They would have told you what the problem is.

#!/usr/bin/perl
use strict;
use warnings;
use Email::Valid;
my $email_address = 'a.n#example.com';
unless( Email::Valid->address($email_address) ) {
print "Sorry, that email address is not valid!";
}
Reference Site: http://learn.perl.org/examples/email_valid.html
For Regex Pattern try this:
my $pattern= '^([a-zA-Z][\w\_\.]{6,15})\#([a-zA-Z0-9.-]+)\.([a-zA-Z]{2,4})$';
Reference Site: https://www.experts-exchange.com/articles/8652/Email-validation-using-Regular-Expression-in-Perl.html

Change your if condition to
if ($string =~ /^[a-z0-9A-Z][A-Za-z0-9.]+[A-Za-z0-9]\#[A-Za-z0-9.-]+$/)
and change
$string = "XYZ#yahoo.com"; to
$string = 'XYZ#yahoo.com';
Refference : http://perlmaven.com/email-validation-using-regular-expression-in-perl
for details.

Try
if ($email =~ /^[a-z0-9]([a-z0-9.]+[a-z0-9])?\#[a-z0-9.-]+$/)
And some test code:
#!/usr/bin/perl
my $email = "john.doe\#acme.org";
if ($email =~ /^[a-z0-9]([a-z0-9.]+[a-z0-9])?\#[a-z0-9.-]+$/) {
print "Valid email\n";
} else {
print "Not valid email\n";
}
exit;
Output:
Valid email

Related

Find words in string

I would like to show in result three words "hidden". I don't know how to do this. Right now, when I start the program, I don't have effect. I see only my text. How to repair it ? I want to create simple program. I have my string and I want to show words which I want to find in my result.
use strict;
my $text='Try to find the hidden string here! Hidden or hidden';
my $a = m/\bhidden\b/;
if ($text=~ $a) {
print "I found word: $a";
}
else {
print "No match, sorry.\n";
}
Let's see how we could debug this problem.
Your first step should be to add use warnings to your code. You should always include both use strict and use warnings. They are like Perl's safety nets and only a foolhardy programmer codes without them.
#!/usr/bin/perl
use strict;
use warnings; # ADDED THIS
my $text='Try to find the hidden string here! Hidden or hidden';
my $a = m/\bhidden\b/;
if ($text=~ $a) {
print "I found word: $a";
}
else {
print "No match, sorry.\n";
}
Now we get a warning:
Use of uninitialized value $_ in pattern match (m//) at test_re line 8.
Line 8 is this:
if ($text=~ $a) {
So let's see what is in $a (as an aside - please don't use $a as a variable name. Firstly, it's a terrible, generic name; and, secondly, Perl uses it as a special variable in the sort function):
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say'; # ADDED THIS
my $text='Try to find the hidden string here! Hidden or hidden';
my $a = m/\bhidden\b/;
say "\$a is [$a]"; # ADDED THIS
if ($text=~ $a) {
print "I found word: $a";
}
else {
print "No match, sorry.\n";
}
Now, as well as our warning, we get this output:
$a is []
I don't think you're expecting $a to be empty at that point, are you? We can go further and determine whether it's an empty string or an undefined value.
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
my $text='Try to find the hidden string here! Hidden or hidden';
my $a = m/\bhidden\b/;
say "\$a is [$a]";
say "\$a is ", (defined $a ? 'defined' : 'undefined'); # ADDED THIS
if ($text=~ $a) {
print "I found word: $a";
}
else {
print "No match, sorry.\n";
}
And we see:
$a is defined
So it's an empty string. What do you expect it to be?
Here's where is it set?
my $a = m/\bhidden\b/;
I'm not sure what you expected this to do, but it actually means "match \bhidden\b and assign the result of the match to $a". And what does it match against that regex? Well, m/.../ matches the contents of$` by default. (That, incidentally, explains our original "uninitialized value $" warning - Perl just got the line number wrong by one.)
So what actually happens on that line is that Perl tries to match \bhidden\b against $_. This fails (as $_ is undefined) and the match returns a false value (the empty string) that gets assigned to $a.
Then your code goes on to run this:
if ($text=~ $a) {
And, as $a is the empty string, it matches (any string will match against an empty string and Perl tells you it has matched $a (which still contains the empty string).
I'm not sure what you were trying to do with this line:
my $a = m/\bhidden\b/;
Perhaps you were trying "pre-compile" the regex in some way. In which case, you were looking for qr/.../, not m/.../.
So maybe you wanted this:
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
my $text = 'Try to find the hidden string here! Hidden or hidden';
my $a = qr/\bhidden\b/; # CHANGED THIS
say "\$a is [$a]";
say "\$a is ", (defined $a ? 'defined' : 'undefined');
if ($text =~ $a) {
print "I found word: $a";
}
else {
print "No match, sorry.\n";
}
Which gives this output:
$a is [(?^:\bhidden\b)]
$a is defined
I found word: (?^:\bhidden\b)
Or, if you want to show what has been matched, rather than the regex that you are matching, then you need to "capture" that text:
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
my $text = 'Try to find the hidden string here! Hidden or hidden';
my $a = qr/\b(hidden)\b/; # CHANGED THIS
say "\$a is [$a]";
say "\$a is ", (defined $a ? 'defined' : 'undefined');
if (my ($matched) = $text =~ $a) { # CHANGED THIS
print "I found word: $matched"; # CHANGED THIS
}
else {
print "No match, sorry.\n";
}
Which gives us:
$a is [(?^:\b(hidden)\b)]
$a is defined
I found word: hidden
Ah, but you want to see all of the words. So capture the matches in an array and use the /g option to match multiple times:
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
my $text = 'Try to find the hidden string here! Hidden or hidden';
my $a = qr/\b(hidden)\b/;
say "\$a is [$a]";
say "\$a is ", (defined $a ? 'defined' : 'undefined');
if (my (#matched) = $text =~ /$a/g) { # CHANGED THIS
print "I found word: #matched"; # CHANGED THIS
}
else {
print "No match, sorry.\n";
}
We now get this:
$a is [(?^:\b(hidden)\b)]
$a is defined
I found word: hidden hidden
That only matches two instances of "hidden" as the match is case-sensitive. So turn off the case sensitivity with /i.
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
my $text = 'Try to find the hidden string here! Hidden or hidden';
my $a = qr/\b(hidden)\b/i; # CHANGED THIS
say "\$a is [$a]";
say "\$a is ", (defined $a ? 'defined' : 'undefined');
if (my (#matched) = $text =~ /$a/g) {
print "I found word: #matched";
}
else {
print "No match, sorry.\n";
}
Which gives us:
$a is [(?^i:\b(hidden)\b)]
$a is defined
I found word: hidden Hidden hidden
But, honestly, I think pre-compiling the regex here is just over-complicating things. I'd write this code like this (removing the $a variable completely):
#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
my $text = 'Try to find the hidden string here! Hidden or hidden';
if (my (#matched) = $text =~ /\b(hidden)\b/gi) {
print "I found word: #matched";
}
else {
print "No match, sorry.\n";
}
Perhaps you are looking for this piece of code
use strict;
use warnings;
use feature 'say';
my $text='Try to find the hidden string here! Hidden or hidden';
my $re = qr/(hidden)/i; # () capture found ignoring case
my #match = $text =~ /$re/g; # g specifies to look for all accurances
say for #match; # output each element of #match
Output
hidden
Hidden
hidden

save key value in two different variables

I'm trying to figure out a way to split a string by delimiter : and save them as two string. I tried something in line 9 but it is not working. Apparently i want to find existence of #clients in #ping_host, if not exist then send an alert. Any suggestion?
#ping_host = ['1232','1212'];
#clients = ['1232:RARB','1212:CBN'];
client_monitor_state(#ping_host);
sub client_monitor_state(#ping_host){
my $token = $properties{token};
#clients = split(/,/, $token);
foreach $client (#clients){
($client_id,$client_name)=m/(\w+)\s*:(.+)/; # here the client_id should have the first part of match string
if(! grep($client_id,#ping_host)){
print "Client noted is $client_name \n";
# mail the client that is not reachable
my $subject_line = "The client $client_name is not reachable";
smtp_send(server_name => $client_name, subject_name => $subject_line);
}
}
}
You should use warnings; because it would probably have hinted at the solution. You are implicitly using $_ instead of $client, and you need to use =~ instead of =
use warnings;
use strict;
my $client = 'this:that';
my ($client_id, $client_name) = $client =~ m/(\w+)\s*:(.+)/;
print "$client_id,$client_name\n";
__END__
this,that

Perl variables becoming empty in if statement

This is driving me crazy, Perl is simply losing the value of a variable once I enter an if statement... and the weird this is, its only that variable, any other variable will not lose its value
open (MYFILE, "b");
my $haysack = "";
while (<MYFILE>)
{
$haysack = $haysack . "$_";
}
close (MYFILE);
open (MYFILE2, "ip_range");
my $needles = "";
while (<MYFILE2>)
{
$needles = $needles . "$_";
}
close (MYFILE2);
my $someOtherValue = "blabla";
while ($needles =~ m/(.*?)\n/g)
{
$needle = $1;
if ($haysack =~ m/$needle/ims)
{
print "FOUND : $needle\n";
print "$someOtherValue\n";
}
}
So the code succesfully enters the if statement, but once it does I get the following output:
FOUND:
blabla
can anyone help?
This really should be a comment, since it's not an answer, but comments don't allow code formatting, so:
Can you provide a complete, runnable, self-contained, minimal example which demonstrates the problem without extraneous moving parts, such as reading files? Something similar to the following:
#!/usr/bin/env perl
use strict;
use warnings;
my $haysack = "Foo
Bar
Baz
";
my $needles = "a
b
c
";
while ($needles =~ m/(.*?)\n/g) {
my $needle = $1;
if ($haysack =~ m/$needle/ims) {
print "FOUND : $needle\n";
}
}
...except that mine runs perfectly, producing the output
FOUND : a
FOUND : b
rather than failing. Note that, in the process of creating a minimal failing example, you are very likely to discover the solution to your problem...
As far as general troubleshooting advice, use strict and use warnings if you aren't already doing so. Check the value of $1 after doing the outer match to verify that $needle will be getting the value you expect it to.

Perl: How to detect which file exists among foo.(txt|abc)

My perl script needs to detect the extension of an existing file and print out the filename. The input that specifies the filename with a vague extension would be in this format:
foo.(txt|abc)
and the script would print "foo.txt" if it exists. If foo.txt does not exist and foo.abc exists, then it would print "foo.abc."
How can I do this detection and printing of the correct existing file in a neat and clean way?
Thanks!
Actually, you've almost got the regular expression right there: the only thing you need to do is escape the . with a backslash (since . means "any character except the newline character" in regular expressions), and it would also help to put a ?: inside of the parentheses (since you don't need to capture the file extension). Also, ^ and $ denote markers for the beginning and the end of the string (so we're matching the entire string, not just part of a string...that way we don't get a match for the file name "thisisnotfoo.txt")
Something like this should work:
use strict;
use warnings;
my $file1="foo.txt";
my $file2="foo.abc";
my $file3="some_other_file";
foreach ($file1,$file2,$file3)
{
if(/^foo\.(?:txt|abc)$/)
{
print "$_\n";
}
}
When the above code is run, the output is:
foo.txt
foo.abc
Take a look at perldoc perlretut for more stuff about regular expressions.
You may want to look at glob, but you'd have to use a different syntax. The equivalent would be:
foo.{txt,abc}
See File::Glob for more information. Also note that this will return a list of all of the matches, so you'll have to do your own rules if it should prefer one when multiple exist.
sub text_to_glob {
my ($s) = #_;
$s =~ s/([\\\[\]{}*?~\s])/\\$1/g;
return $s;
}
my $pat = 'foo.(txt|abc)';
my #possibilities;
if (my ($base, $alt) = $pat =~ /^(.*\.)\(([^()]*)\)\z/s) {
#possibilities = glob(
text_to_glob($base) .
'{' . join(',', split(/\|/, $alt)) . '}'
);
} else {
#possibilities = $pat;
}
for my $possibility (#possibilities) {
say "$possibility: ", -e $possibility ? "exists" : "doesn't exist";
}
glob, but also see File::Glob
-e
use strict;
use warnings;
FILE:
for (glob "file.{txt,abc}") {
if (-f $_) {
print $_, "\n";
last FILE;
}
}

Regular Expression for # Array in Perl

Actually i m using one perl script to prepare Readme txt for my builds. in that script i used
foreach $line (<LOG>)
{
if(length(trim($line))>0)
{
$line=trim($line);
$line=~ s/[\r]//gs;
if(rindex($line,'#')!=-1)
{
$icut=substr($line,0,index($line,']'));
$icut2=substr($icut,index($icut,'#')+1,length($icut));
}
push(#issue,$icut2);
it's fetching correct issue no but when the situation comes like
[I#1303350], [I#1270918],[I#1312521] Updated Physical Confirmation Template based on CO
then it's fetching only one issue no not all issue i that same line. so i modified my code like
foreach $revno(<REV>)
{
if(length(trim($revno))>0)
{
$revno=trim($revno);
$revno=~ s/[\r]//gs;
if(rindex($revno,'#')!=-1)
{
$revcut=substr($revno,0,rindex($revno,']'));
print "$revcut\n";
$revcut1=substr($revcut,index($revcut,'#')+1,length($revcut));
}
}
push(#issue,$revcut1);
now it's fetch it all revision no but output is like 1312588,1303350], [I#1270918],[I#1312521 but i want to remove the # [ ] I only but not , so pls tell me how can i parse this through regex.
This can be done without regular expressions: Transliterate: tr///
use warnings;
use strict;
my $s = '1312588,1303350], [I#1270918],[I#1312521';
$s =~ tr/ ][#I//d;
print "$s\n";
__END__
1312588,1303350,1270918,1312521
You can do it like this:
echo "[I#1303350], [I#1270918],[I#1312521]" | perl -lnwe "print for m/#(\d+)/g"
This works for me:
my #issues = $line_of_data =~ m/#(\d+)/g;
And if you want commas, it's far easier to do this:
my $with_commas = join( ', ', #issues );
And you still have the individual issues numbers as "atoms" of data.