WeBWorK Problems

Regex delimiters

Regex delimiters

by Steven Fiedler -
Number of replies: 1

I hunted down the source of some unexpected output while developing a problem as the delimiter in regular expressions.  Below are two minimal working examples in pg and perl respectively with the lines identified parenthetically,

     $n=~'\d'  (single quotes)

versus,

      $n=~/\d/  (slash)

as the salient portions.  The single quote method works as I expected in pg but the slash does not.  In perl both characters work identically in the expected manner.  Naively, it appears that the single quote should be used for all such regex cases in pg going forward, but I would appreciate further insight.

----------------------------------------------------------------------------------------------------------------

PG output

Slash delimiter value: 11
Quote delimiter value: 10

----------------------------------------------------------------------------------------------------------------

Perl output

Slash delimiter value: 10
Quote delimiter value: 10

----------------------------------------------------------------------------------------------------------------

PG code

DOCUMENT();
loadMacros("PGstandard.pl" );

$input=123.45;

BEGIN_TEXT
Slash delimiter value: \{slash($input)\}$BR
Quote delimiter value: \{quote($input)\}$BR
END_TEXT

sub quote {
  my($n)  = @_;
  if( $n=~'\d'){return 10;}
  else{return 11;}
}

sub slash {
  my($n)  = @_;
  if( $n=~/\d/){return 10;}
  else{return 11;}
}

ENDDOCUMENT();

----------------------------------------------------------------------------------------------------------------

Perl code

$input=123.45;
$ret1=slash($input);
$ret2=quote($input);
print "Slash delimiter value: $ret1\n";
print "Quote delimiter value: $ret2\n";

sub quote {
  my($n)  = @_;
  if( $n=~'\d'){return 10;}
  else{return 11;}
}

sub slash {
  my($n)  = @_;
  if( $n=~/\d/){return 10;}
  else{return 11;}
}






In reply to Steven Fiedler

Re: Regex delimiters

by Alex Jordan -

In PG, when you have a backslash in your code it will be translated into a double backslash before perl does any interpolation. Your:

$n=~/\d/

becomes:

$n=~/\\d/

and then perl is looking for a
backslash d
not looking for a digit.

It appears that the translator is not doing this when the backslash is inside single quotes.

The reason this happens has to do with backslash also being the LaTeX escape character. So in a math expression, you don't want perl to turn your \frac into whatever \f is followed by rac. The translator makes it \\frac, before perl processes it back to \frac.

And if you really need a backslash, PG lets you use ~~. So your example can be:

$n=~/~~d/

And the translator stage will turn the ~~ into a single backslash before perl processes things further.