--------------080202040905030102040008
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hello Lionel,
That was quite a quiz you asked us
I have a solution using only 'regular' regular expressions, the one in
1.8.1. Thus: this solution works without oniguruma.
I work around the lookbehind trouble by appending three spaces in front
of the string.
I am sure this solution is hideously complicated and can be improoved.
Anyone ?
Here's the output:
~ bluna ${var\}weird}
~ bluna weird substitute
~ sh ${tool} -o ${target} -L${libpath} -l${lib} ${source}
~ sh gcc -o test.exe -L/usr/lib -lopengl render.c
~ \${var}
~ \${var}
~ \\${var}
~ \\rvar
~ $\${var}
~ $\${var}
~ $\$${var}
~ $\$rvar
with an env of
~ env = {
'var\}weird' => 'weird substitute',
'var' => 'rvar',
'tool' => 'gcc',
'target' => 'test.exe',
'libpath' => '/usr/lib',
'lib' => 'opengl',
'source' => 'render.c'
~ }
Hope this hits your nerv,
kaspar
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)
Comment: Using GnuPG with Thunderbird -
http://enigmail.mozdev.org
iD8DBQFBbmnPFifl4CA0ImQRAjF/AJ4oweuSNuxknxcslsv0f3S9GFiebACfXO7B
GYygYzZW0Co4z5S2na7y5Os=
=wcON
-----END PGP SIGNATURE-----
--------------080202040905030102040008
Content-Type: text/plain;
name="interpolation.rb"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="interpolation.rb"
tests = []
tests << 'bluna ${var\\}weird}'
tests << 'sh ${tool} -o ${target} -L${libpath} -l${lib} ${source}'
tests << '\\${var}'
tests << '\\\\${var}'
tests << '$\${var}'
tests << '$\$${var}'
env = {
'var\}weird' => 'weird substitute',
'var' => 'rvar',
'tool' => 'gcc',
'target' => 'test.exe',
'libpath' => '/usr/lib',
'lib' => 'opengl',
'source' => 'render.c'
}
class ShellExpander
REString = /
^
(?:
\\ . |
[^\\$] |
\$ \\ . |
\$ [^\\{]
){3,}
\$ \{
(
(?: \\ . | [^\\}] )*
)
}
/x
def initialize env={}
@env = env
end
# call-seq:
# #expand( str ) => str
def expand str
for_each_shell_expansion_in str do |var|
@env[var]
end
end
def for_each_shell_expansion_in str
tomatch = str
replacements = []
offset = 0
while str.length > 0
tomatch = ' '*3 + tomatch
offset -= 3
md = REString.match tomatch
break unless md
replacement = yield( md[1] )
i, j = offset+md.begin(1), offset+md.end(1)
replacements << [i, j, replacement] if replacement
offset += md.pre_match.length + md[0].length
tomatch = md.post_match
end
offset = 0
replacements.each do |from, to, rep|
str[ (offset+from-2)...(offset+to+1) ] = rep
offset += rep.length - (to-from+3)
end
str
end
end
expander = ShellExpander.new env
tests.each do |str|
puts
puts str
puts expander.expand(str)
end
--------------080202040905030102040008--