I use smartmatch to check whether a string matches a regex pattern. It stopped working after I decided to store the regex in a text file.
my $str = '123456, some text.';
my $regex = qr/^\d+, some text\.$/;
print "Regex: $regex\n";
At this point, the printed regex is (?^:^\d+, some text\.$)
. I copy-paste it into a file, then I make the code read the file and retrieve the regex, which is stored in $regexFromFile
.
The following line confirms that $regex
and $regexFromFile
are the same, then I proceed to test $str
against the regex in various ways.
print 'Is regex equal to regexFromFile? ' . ($regex eq $regexFromFile) . "\n";
print 'Does str match regex using =~ ? ' . ($str =~ $regex) . "\n";
print 'Does str match regexFromFile using =~ ? ' . ($str =~ $regexFromFile) . "\n";
print 'Does str match regex using ~~ ? ' . ($str ~~ $regex) . "\n";
print 'Does str match regexFromFile using ~~ ? ' . ($str ~~ $regexFromFile) . "\n";
The last line of that code does not behave the same as the previous three lines.
Here is the complete output of the code:
Regex: (?^:^\d+, some text\.$)
Is regex equal to regexFromFile? 1
Does str match regex using =~ ? 1
Does str match regexFromFile using =~ ? 1
Does str match regex using ~~ ? 1
Does str match regexFromFile using ~~ ?
(Note the absence of 1
at the end.)
Edit: To answer a comment, here is how the file is read.
open(my $FILEHANDLE, 'file.txt') or die "Error: Could not open file.\n";
my @content = <$FILEHANDLE>;
close($FILEHANDLE) or print "Could not close file.\n";
my @content_woEol = ();
foreach my $line (@content){
$line =~ s/\s*$//;
push(@content_woEol, $line);
}
my $regexFromFile = $content_woEol[0];
The result of qr//
is actually a precompiled regular expression. Copy-pasting the printed regular expression to a file, as you did, then reading it from the file, is not the problem. You would experience the same behavior had you written this line directly in your code:
my $regexFromFile = '(?^:^\d+, some text\.$)';
If you want to use smatmatch here, I would advise you to do something like the following:
my $str = '123456, some text.';
my $regex = '^\d+, some text\.$';
# Manually store this in the file: ^\d+, some text\.$
# Read $regexFromFile from the file
print 'Does str match regex using =~ ? ' . ($str =~ /$regex/) . "\n";
print 'Does str match regexFromFile using =~ ? ' . ($str =~ /$regexFromFile/) . "\n";
print 'Does str match regex using ~~ ? ' . ($str ~~ /$regex/) . "\n";
print 'Does str match regexFromFile using ~~ ? ' . ($str ~~ /$regexFromFile/) . "\n";
Note the additional /.../
. Output:
Does str match regex using =~ ? 1
Does str match regexFromFile using =~ ? 1
Does str match regex using ~~ ? 1
Does str match regexFromFile using ~~ ? 1