time ago a monk asked how to s/// using an hash for key/value substitution.
knowing the keys of the hash, it would be easy to:
in a more generic way, the RE can be built using qr:s/(key1|key2|key3)/$hash{$1)/g;
with a CPAN module, you can:my $re = join '|', keys %dict; $re = qr|($re)|; s/$re/$hash{$1}/g;
which returns a more clever pattern. Or:use Regexp::Assemble; my $ra = Regexp::Assemble->new; $ra->add($_) for keys %dict;
(Note some differences between those approaches. The last one will "update" the string also when it shouldn't, by replacing with the same text. this can be a problem if i want to match 'bcd' in 'abcde' -- in this case s/// will change abcde with abcde and pass over, it does not check bcd!)s/(\w+)/$dict{$1}||$1/ge;
I looked on perlre to findout if we can do assertions on a RE, (?{code}) is an "always true" statement1, a pity we can't use to stop the parsing. but after some digging i found that (?(?{cond})|(?!)) fails if cond isn't true, so:
This way avoid to prepare the RE before, but match bcd against abcde.s/(\w+)(?(?{$dict{$1}})|(?!))/$dict{$1}/g;
This seems to be a misleading (yet usefull) feature. it means that (${code}) isn't an "always true" assertion. But is it reliable enough to be used?
1 -- seems this will be changed in perl 6.
Update: corrected a missing ) in the last RE.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: regex s/// using hash
by ikegami (Patriarch) on Oct 16, 2007 at 13:40 UTC | |
by oha (Friar) on Oct 16, 2007 at 13:48 UTC | |
by ikegami (Patriarch) on Oct 16, 2007 at 13:57 UTC | |
by oha (Friar) on Oct 16, 2007 at 14:01 UTC | |
by ikegami (Patriarch) on Oct 16, 2007 at 14:06 UTC | |
| |
|
Re: regex s/// using hash
by moritz (Cardinal) on Oct 16, 2007 at 14:17 UTC | |
|
Re: regex s/// using hash (heavy backtracking)
by lodin (Hermit) on Oct 16, 2007 at 20:37 UTC |