regex challenge

Here's a regex substitution operation that has stumped me with sed:

How do you convert lines like this:

first.key ?{x.y.z}
second.key ?{xa.ys.zz.s}
third.key ?{xa.k}

to:

first.key ?{x_y_z}
second.key ?{xa_ys_zz_s}
third.key ?{xa_k}

So i'm basically converting all the periods within the ?{...} structure to underscores, without changing the periods outside of this structure?

if u don't mind, i can try this in awk instead of sed

awk -v FS='[}{]' '{gsub(/\./,"_",$2); print $1"{"$2"}"}' /path/of/file
$ cat data
first.key ?{x.y.z}
second.key ?{xa.ys.zz.s}
third.key ?{xa.k}
$ sed -e :a -e's/\([^{][^{]*{[^.][^.]*\)\./\1_/;ta' < data
first.key ?{x_y_z}
second.key ?{xa_ys_zz_s}
third.key ?{xa_k}
$
$

This can probably be simplified; however, obvious simplifications did not seem to work. :confused: It's trickier than it looks.

sed -e :a -e's/\([^{]\+{[^.]\+\)\./\1_/;ta' < data

This simplification worked for me.... interesting, I did not know about the "t" operator.

Sweet thinking!

Thanks Perderabo and gnsxhj... I'm still, however, interested in a pure (or purer?) regex solution.

$ cat file
first.key ?{x.y.z}
second.key ?{xa.ys.zz.s}
third.key ?{xa.k}
$ perl -pe's/([^.]+)\.(?!\w+\s)/$1_/g' file
first.key ?{x_y_z}
second.key ?{xa_ys_zz_s}
third.key ?{xa_k}

Pure regular expressions only match a string; it doesn't get much purer than the sed solutions you already got.

Here is an easy ( beautiful ? :wink: ) hack

sed 's/\./#/;s/\./_/g;s/#/\./' filename

Nice!
For multiple dots in the first part (before the opening brace):

$ perl -pe's/([^.]+)\.(?!.+{)/$1_/g'<<<'f.i.r.s.t.key ?{x.y.z}'
f.i.r.s.t.key ?{x_y_z}

Or with a negative lookahead assertion,

perl -pe 's/\.(?!.*\?\{)/_/g'

Yes,
this is more succinct and efficient.