From: Mr P on
Lets say I want the CENTER 2 characters from any (even length) string?

123456 .. 34
ABC123 .. C1
1223 ..22
1234567890 .. 56
AB .. AB


is there A regex that can handle this for ANY even length string? Im
pretty good with regexes but I cant think of one that can handle it.

sorta like
s/(.+)(..)(.+)/$2/ where the length of $1 == length of $2..

Thanks!
From: Jozxyqk on
Mr P <misterperl(a)gmail.com> wrote:
> Lets say I want the CENTER 2 characters from any (even length) string?

> is there A regex that can handle this for ANY even length string? Im
> pretty good with regexes but I cant think of one that can handle it.

Why use a regex?

substr($string,length($string)/2-1,2);

From: Ben Morrow on

Quoth Mr P <misterperl(a)gmail.com>:
> Lets say I want the CENTER 2 characters from any (even length) string?
>
> 123456 .. 34
> ABC123 .. C1
> 1223 ..22
> 1234567890 .. 56
> AB .. AB
>
>
> is there A regex that can handle this for ANY even length string? Im
> pretty good with regexes but I cant think of one that can handle it.
>
> sorta like
> s/(.+)(..)(.+)/$2/ where the length of $1 == length of $2..

Well, the obvious way would be

/(.+)(..)(??{ "." x length $1 })/

In principle it ought to be possible to do this by treating it as a
bracketed construct, using the new recursion primitives in 5.10, but
while

/^( . (?: (..) | (?1) ) . )$/x

performs the match correctly, the recursion resets $2 so you lose the
capture. This can be fixed with

use vars qw/$centre/;
/^( . (?: (..)(?{ $centre = $2 }) | (?1) ) . )$/x

but IIRC referencing lexicals is one of the things you mustn't do from
within a (?{}) group (there are nasty bugs here) so you have to use a
package global instead.

Ben

From: Mr P on
On Jul 14, 3:44 pm, Ben Morrow <b...(a)morrow.me.uk> wrote:
> Quoth Mr P <misterp...(a)gmail.com>:
>
> > Lets say I want the CENTER 2 characters from any (even length) string?
>
> > 123456 .. 34
> > ABC123 .. C1
> > 1223 ..22
> > 1234567890 .. 56
> > AB .. AB
>
> > is there A regex that can handle this for ANY even length string?  Im
> > pretty good with regexes but I cant think of one that can handle it.
>
> > sorta like
> > s/(.+)(..)(.+)/$2/  where the length of $1 == length of $2..
>
> Well, the obvious way would be
>
>     /(.+)(..)(??{ "." x length $1 })/
>
> In principle it ought to be possible to do this by treating it as a
> bracketed construct, using the new recursion primitives in 5.10, but
> while
>
>     /^( . (?: (..) | (?1) ) . )$/x
>
> performs the match correctly, the recursion resets $2 so you lose the
> capture. This can be fixed with
>
>     use vars qw/$centre/;
>     /^( . (?: (..)(?{ $centre = $2 }) | (?1) ) . )$/x
>
> but IIRC referencing lexicals is one of the things you mustn't do from
> within a (?{}) group (there are nasty bugs here) so you have to use a
> package global instead.
>
> Ben

Ahh very helpful Ben thanks!
From: Mr P on
On Jul 14, 2:32 pm, Jozxyqk <jfeue...(a)eecs.tufts.edu> wrote:
> Mr P <misterp...(a)gmail.com> wrote:
> > Lets say I want the CENTER 2 characters from any (even length) string?
> > is there A regex that can handle this for ANY even length string?  Im
> > pretty good with regexes but I cant think of one that can handle it.
>
> Why use a regex?
>
> substr($string,length($string)/2-1,2);

I'd thought of this approach and even played with it a bit- you left
out the test for *evenness* however. I just love regexes I'd hoped
there was something simple Id missed like some assertion that would
make it EZ.. Ben's solution is pretty durn good though!