Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Dynamic regular expressions

2 views
Skip to first unread message

Real

unread,
Feb 4, 2002, 9:05:31 AM2/4/02
to
Hello everybody,

I'm trying to change a certain text using dynamic regular expressions. Both
the pattern and the replacement are in variables. This works fine except
when using buffers as in "The bracketing construct ( ... ) creates capture
buffers" (see perlre documentation).

Below is an example which tells it all. The first replacement is hard-coded
and the two words are swapped. In the second example, the results are *not*
the two words but buffer-references ($1 and $2).

I tried using eval and backtracking replacements but without any luck. Does
anyone have a clue of how to solve this ?

BTW: I'm using Perl, version 5.005_03 built for sun4-solaris

Thanks very much in advance,
Real

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
#!/usr/local/bin/perl -w

use strict;

my($text, $exp1, $exp2);

$text = 'one two';
$text =~ s/^([^ ]*) *([^ ]*)/$2 $1/;

print "First: $text\n";


$text = 'one two';
$exp1 = '^([^ ]*) *([^ ]*)';
$exp2 = '$2 $1';

$text =~ s/$exp1/$exp2/;

print "Second: $text\n";


exit;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -

Jeff 'japhy' Pinyan

unread,
Feb 4, 2002, 9:18:02 AM2/4/02
to
On Feb 4, Real said:

>I tried using eval and backtracking replacements but without any luck. Does
>anyone have a clue of how to solve this ?

Here are two ideas:

>$text = 'one two';
>$exp1 = '^([^ ]*) *([^ ]*)';

$exp2 = sub { "$2 $1" };
$text =~ s/$exp1/$exp2->()/e;

Or:

>$text = 'one two';
>$exp1 = '^([^ ]*) *([^ ]*)';
>$exp2 = '$2 $1';

$text =~ s/$exp1/qq["$exp2"]/ee;

--
Jeff "japhy" Pinyan ja...@pobox.com http://www.pobox.com/~japhy/
RPI Acacia brother #734 http://www.perlmonks.org/ http://www.cpan.org/
** Look for "Regular Expressions in Perl" published by Manning, in 2002 **
<stu> what does y/// stand for? <tenderpuss> why, yansliterate of course.

Lack Mr G M

unread,
Feb 4, 2002, 11:07:23 AM2/4/02
to
In article <a3m4ff$5ra$1...@news.surfnet.nl>, "Real" <re...@earthling.net> writes:
|>
|> I tried using eval and backtracking replacements but without any luck. Does
|> anyone have a clue of how to solve this ?
|>...

|> $text = 'one two';
|> $exp1 = '^([^ ]*) *([^ ]*)';
|> $exp2 = '$2 $1';
|>
|> $text =~ s/$exp1/$exp2/;

eval "\$text =~ s/$exp1/$exp2/";

You have to protect the $text variable from being expanded (to its
contents) while the code line is being "calculated".


--
--------- Gordon Lack --------------- gml...@ggr.co.uk ------------
This message *may* reflect my personal opinion. It is *not* intended
to reflect those of my employer, or anyone else.

Uri Guttman

unread,
Feb 4, 2002, 11:57:59 AM2/4/02
to
>>>>> "LMGM" == Lack Mr G M <gml...@ggr.co.uk> writes:

LMGM> In article <a3m4ff$5ra$1...@news.surfnet.nl>, "Real" <re...@earthling.net> writes:
LMGM> |>
LMGM> |> I tried using eval and backtracking replacements but without any luck. Does
LMGM> |> anyone have a clue of how to solve this ?
LMGM> |>...
LMGM> |> $text = 'one two';
LMGM> |> $exp1 = '^([^ ]*) *([^ ]*)';
LMGM> |> $exp2 = '$2 $1';
LMGM> |>
LMGM> |> $text =~ s/$exp1/$exp2/;

LMGM> eval "\$text =~ s/$exp1/$exp2/";

huh? there is no need for eval there. where did you get that idea?
regexes and s/// can interpolate fine.

if you need to set which $1 vars you want, use the /e modifier. but a
full string eval is silly and wasteful.

uri

--
Uri Guttman ------ u...@stemsystems.com -------- http://www.stemsystems.com
-- Stem is an Open Source Network Development Toolkit and Application Suite -
----- Stem and Perl Development, Systems Architecture, Design and Coding ----
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org

Brian McCauley

unread,
Feb 4, 2002, 1:42:57 PM2/4/02
to
Jeff 'japhy' Pinyan <je...@crusoe.net> writes:

> On Feb 4, Real said:
>
> >I tried using eval and backtracking replacements but without any luck. Does
> >anyone have a clue of how to solve this ?
>
> Here are two ideas:
>
> >$text = 'one two';
> >$exp1 = '^([^ ]*) *([^ ]*)';
>
> $exp2 = sub { "$2 $1" };
> $text =~ s/$exp1/$exp2->()/e;

Personally I'd always quote a regex with qw// not '' and dereference a
CODE ref that communucates via global variables with &, if only for
sylistic reasons.

$text = 'one two';
$exp1 = qr/^([^ ]*) *([^ ]*)/;


$exp2 = sub { "$2 $1" };

$text =~ s/$exp1/&$exp2/e;

And here's a third that may, sometimes, be more appropriate:

> >$text = 'one two';
> >$exp1 = '^([^ ]*) *([^ ]*)';
> >$exp2 = '$2 $1';

$text = 'one two';
$subst = sub { s/^([^ ]*) *([^ ]*)/$2 $1/ };

&$subst for $text;

--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\

Jeff 'japhy' Pinyan

unread,
Feb 4, 2002, 4:36:54 PM2/4/02
to
On Feb 4, Brian McCauley said:

>Jeff 'japhy' Pinyan <je...@crusoe.net> writes:
>
>> >$exp1 = '^([^ ]*) *([^ ]*)';
>>
>> $exp2 = sub { "$2 $1" };
>> $text =~ s/$exp1/$exp2->()/e;
>
>Personally I'd always quote a regex with qw// not '' and dereference a
>CODE ref that communucates via global variables with &, if only for
>sylistic reasons.

Yes, I use qr// too (being the regex freak I am). I tend not to use the
&-method of calling functions, ever. The only time I use & in a function
related context is when making a reference to one. That's just how I
operate.

Benjamin Goldberg

unread,
Feb 6, 2002, 1:32:00 AM2/6/02
to
Uri Guttman wrote:
> >>>>> "LMGM" == Lack Mr G M <gml...@ggr.co.uk> writes:
[snip]

> LMGM> eval "\$text =~ s/$exp1/$exp2/";
>
> huh? there is no need for eval there. where did you get that idea?
> regexes and s/// can interpolate fine.
>
> if you need to set which $1 vars you want, use the /e modifier. but a
> full string eval is silly and wasteful.

Of course, you do realize that to do it with /e, you either need
multiple e's (in other words, full string eval), or you need to parse
out your dollar-digit variables yourself?

Anyway, I would do without eval entirely:

my $exp1 = '^([^ ]*) *([^ ]*)';
my $exp2_from_wherever = '$2 $1';
my $exp2 = do {
my @parts = \(split /\$(\d+)/, $exp2_from_wherever);
no strict 'refs';
$_ = \${$$_ + 0} for @parts[grep $_ % 2, 1 .. $#parts];
use strict;
sub { join "", map $$_, @parts };
};
$text =~ s/$exp1/$exp2->()/e;

--
A child of 5 could understand this! Fetch me a child of 5

0 new messages