Bug #9450

variables embedded in regexps are not expanded

Added by Steve Shipway almost 2 years ago. Updated 20 days ago.

Status:AcceptedStart date:09/12/2011
Priority:NormalDue date:
Assignee:-% Done:

0%

Category:language
Target version:-
Affected Puppet version:2.6.8 Branch:
Keywords:regexp
regular expression
variable

Description

This doesn’t define the notify resource:

$foo = "bar"
$bar = "bar"
if $bar =~ /$foo/ {
   notify { bar: message=>"BAR"; }
}

It seems that variables within regexps are not being expanded. This is a problem for us as we’re trying to define new resources that check facts for parameterised content via a regexp.

History

#1 Updated by James Turnbull almost 2 years ago

  • Description updated (diff)

#2 Updated by James Turnbull almost 2 years ago

  • Category set to language
  • Status changed from Unreviewed to Needs More Information

Perhaps try enclosing the variable in double quotes?

#3 Updated by Steve Shipway almost 2 years ago

Have tried:

/$foo/
/${foo}/
/#{foo}/
/"$foo"/

None work. We’re using Puppet 2.6.8 though so possibly this is corrected in a later version?

#4 Updated by James Turnbull almost 2 years ago

It may have been – could you please try a 2.7.x release and see if it’s still an issue?

#5 Updated by Steve Shipway almost 2 years ago

Im not able to update our production puppet server at the moment and I dont have a dev one handy. Might be a long time before I can test on a different version. Can you test there and confirm if it works or not on 2.7.x?

#6 Updated by James Turnbull almost 2 years ago

  • Status changed from Needs More Information to Accepted

Hmm looks like this is still broken in 2.7.3.

#7 Updated by Henrik Lindberg 9 months ago

It is not really possible to generally expand variables inside a regular expression that way – as a $ has significance inside a regular expression. It would be possible to exploit that $ means “end of input”, and that the /$a/ is special in that, nothing can be matched after the “end of input”.

Another solution would be to relax the =~ operator (it now only accepts a literal regular expression on the RHS. I can imagine a function that constructs a regular expression pattern. The above example would then be written: if $bar =~ pattern($foo) or sweetened to if $bar =~ $foo (i.e. compile content of $foo as pattern). This makes it possible to also use interpolation etc. to construct the pattern `if $bar =~ “${foo}[${acceptable_chars}]”.

The problems regarding recognition of variables inside the regular expression is mainly a lexical one. There is already significant problems recognizing the regular expression as it clashes with division / – thus, it may only appear in certain well defined places where a division may not.

It would be possible to allow support other ways to construct literal regular expressions (ruby has several alternatives), but it is really sufficient to just have a function that does this provided that the expressions that accept a literal regexp are relaxed to match against an expression producing a regexp.

To summarize – I propose:

  • operator =~ compiles its RHS to a regexp if it does not evaluate to one already
  • a regexp function constructs a regexp out of its argument(s) with the same semantics as the compilation of the =~ RHS evaluation

#8 Updated by Erik Dalén 20 days ago

A regexp function wouldn’t really work as that would also allow you to store regexps in variables and use them where ever you can use variables.

Also available in: Atom PDF