regex_replace to print match

23 views
Skip to first unread message

tentaculartentacle

unread,
Sep 20, 2016, 6:24:13 AM9/20/16
to help-cfengine
Hi,

With regex_replace, is there a way to do the equivalent of:  sed 's/foobar:\(.*\)/barfoo:\1/g' 
I mean specifically the \1.

This: regex_replace("foobar:\(.*\),"barfoo:\1")
does not work, and I've tried escaping the parentheses/backslashes in every way I can think of...

If not, any other suggestion short of a "commands" promise?

Shane McEwan

unread,
Sep 20, 2016, 7:48:58 AM9/20/16
to help-c...@googlegroups.com
I haven't had a need for using matched values from regular expressions
in CFEngine yet but according to the documentation[1] it looks like the
matches get turned into CFEngine variables.

So you should be able to do:

regex_replace("foobar:\(.*\),"barfoo: $(match.1)")

[1]
https://docs.cfengine.com/docs/3.5/manuals-language-concepts-pattern-matching-and-referencing.html

Shane.

tentaculartentacle

unread,
Sep 20, 2016, 8:14:42 AM9/20/16
to help-cfengine

Thanks, that works!
I was looking at the cfengine reference docs, which makes no mention of this feature.

Ted Zlatanov

unread,
Sep 20, 2016, 9:33:00 AM9/20/16
to help-c...@googlegroups.com
On Tue, 20 Sep 2016 05:14:41 -0700 (PDT) tentaculartentacle <fred.o...@gmail.com> wrote:

t> I was looking at the cfengine reference docs, which makes no mention of
t> this feature.

The docs say to use `$1` or `\1` and show examples with each one:

https://docs.cfengine.com/docs/master/reference-functions-regex_replace.html

I wrote the implementation and docs of that function. If `$(match.1)`
works somehow, it's not intentional and I wouldn't rely on it; the code
definitely doesn't support it.

Ted

Aleksey Tsalolikhin

unread,
Sep 20, 2016, 3:53:18 PM9/20/16
to help-cfengine
I am surprised to hear that regex_replace() does not use match.1 for the back-reference.

This conflics with https://docs.cfengine.com/lts/reference-special-variables-match.html which states that each time CFEngine matches a string, the values are assigned to match.X.  Do we need to update the documentation? The function?

The fine documentation states:

match

Each time CFEngine matches a string, these values are assigned to a special variable context $(match.*n*). The fragments can be referred to in the remainder of the promise. There are two places where this makes sense. One is in pattern replacement during file editing, and the other is in searching for files.

I am sure the function is excellent too.  :-)   

Yours fondly,

-at


-- 
Need training on CFEngine, Git or Time Management?  Email trai...@verticalsysadmin.com.


--
You received this message because you are subscribed to the Google Groups "help-cfengine" group.
To unsubscribe from this group and stop receiving emails from it, send an email to help-cfengine+unsubscribe@googlegroups.com.
To post to this group, send email to help-c...@googlegroups.com.
Visit this group at https://groups.google.com/group/help-cfengine.
For more options, visit https://groups.google.com/d/optout.

Ted Zlatanov

unread,
Sep 21, 2016, 9:57:46 AM9/21/16
to help-c...@googlegroups.com
On Tue, 20 Sep 2016 12:52:56 -0700 Aleksey Tsalolikhin <ale...@verticalsysadmin.com> wrote:

AT> I am surprised to hear that regex_replace() does not use match.1 for the
AT> back-reference.

AT> This conflics with
AT> https://docs.cfengine.com/lts/reference-special-variables-match.html which
AT> states that each time CFEngine matches a string, the values are assigned to
AT> match.X. Do we need to update the documentation? The function?

They are different things. The `match` special variables are CFEngine
variables for editing *promises*. $1 and \1 are PCRE variables. Inside
the *function call*, PCRE is running directly to do the replacement. If
you involve CFEngine variables at that level, you have to:

* protect `$(match.1)` from early evaluation before PCRE runs (this is
the hard part)

* write the PCRE glue to understand `$(match.1)` and translate it to \1

* diverge from how pretty much every other PCRE invocation works ($1 and
\1 are a VERY standard way to specify backreferences)

So I'd rather not teach regex_replace() about `$(match.1)`.

AT> The fine documentation states:

AT> match

AT> Each time CFEngine matches a string, these values are assigned to a special
AT> variable context $(match.*n*). The fragments can be referred to in the
AT> remainder of the promise. There are two places where this makes sense. One
AT> is in pattern replacement during file editing, and the other is in
AT> searching for files.

The docs should be clarified: they only refer to editing promises. Right
now that's only implied by the last two sentences.

Ted


Reply all
Reply to author
Forward
0 new messages