<?xml version="1.0" encoding="windows-1252"?>
<node id="429761" title="Re: Massive regexp search and replace" created="2005-02-10 10:08:53" updated="2005-08-06 01:50:33">
<type id="11">
note</type>
<author id="29008">
grinder</author>
<data>
<field name="doctext">
&lt;blockquote&gt;&lt;i&gt; Can anyone help me find an efficient implementation.&lt;/i&gt;&lt;/blockquote&gt;

&lt;p&gt;If the cost of a subroutine call is cheaper than scanning the list (which I suspect is the case), then you can assemble all the target patterns into one, perform a single match, and then dispatch to the sub that gives you what you want to substitute:&lt;/p&gt;

&lt;code&gt;
#! /usr/local/bin/perl -w

use strict;
use Regexp::Assemble;

my $ra;

my %dispatch = (
    'food'   =&gt; sub { 'pizza' },
    'water'  =&gt; sub { 'beer'  },
    'like'   =&gt; sub { 'enjoy' },
    '(\d+)F' =&gt; sub { int(($ra-&gt;mvar(1) - 32 ) * 5/9 ) . 'C' },
);

$ra = Regexp::Assemble-&gt;new( track =&gt; 1 )-&gt;add( keys %dispatch );

while( &lt;DATA&gt; ) {
    while( $ra-&gt;match($_) ) {
        my $m = $ra-&gt;matched;
        s/$m/&amp;{$dispatch{$m}}/e;
    }
    print;
}

__DATA__
I'd like a glass of water with my food, it's 92F in here!
&lt;/code&gt;

&lt;p&gt;... produces...&lt;/p&gt;

&lt;code&gt;
I'd enjoy a glass of beer with my pizza, it's 33C in here!
&lt;/code&gt;

&lt;p&gt;Generating the dispatch table from a data file is left as an exercise to the reader (but a pretty fun one, I might say).&lt;/p&gt;
&lt;div class="pmsig"&gt;&lt;div class="pmsig-29008"&gt;
&lt;p align="right"&gt;&lt;font size="-2"&gt;- another intruder with the mooring in the heart of the Perl&lt;/font&gt;&lt;/p&gt;
&lt;/div&gt;&lt;/div&gt;</field>
<field name="root_node">
429692</field>
<field name="parent_node">
429692</field>
</data>
</node>
