How do I write this regex?

Discussion in 'Perl Misc' started by spydox@gmail.com, Jan 24, 2006.

  1. Guest

    This is NOT homework!

    I want to comment out certain lines which immediately follow (as a
    group) another line. I created a simple example:

    $_ = 'ZBCAACBABE';

    In English, for any group of A,B,or C's in any order, which follow a Z,
    I want to preceed with ! . So in this example I want the regex to
    produce:

    Z! B! C! A! A! C! B! A! BE

    I tried ?= but I don't see a way to make that work. I thought

    s/(Z)(A|B|C)+/$1! $2/g;

    might have a chance but it produced

    'Z! BE'

    I'm not sure I can explain that result.

    If your suggestion involves a loop please dont make it, I know plenty
    of ways to do that.

    Thank-You
    , Jan 24, 2006
    #1
    1. Advertising

  2. Paul Lalli Guest

    wrote:
    > This is NOT homework!


    My, my. Mighty defensive, aren't we?

    > I want to comment out certain lines which immediately follow (as a
    > group) another line. I created a simple example:
    >
    > $_ = 'ZBCAACBABE';
    >
    > In English, for any group of A,B,or C's in any order, which follow a Z,
    > I want to preceed with ! .


    Try better English. An object for your transitive verb "preceed" would
    be nice, for example.

    > So in this example I want the regex to produce:
    >
    > Z! B! C! A! A! C! B! A! BE
    >
    > I tried ?= but I don't see a way to make that work. I thought
    >
    > s/(Z)(A|B|C)+/$1! $2/g;
    >
    > might have a chance but it produced
    >
    > 'Z! BE'
    > I'm not sure I can explain that result.


    Because your last parenthesized group has a + modifer. So when all is
    said and done, $2 contains the *last* A, B, or C that it found. And
    you replaced everything matched with $1, a !, and $2.

    > If your suggestion involves a loop please dont make it, I know plenty
    > of ways to do that.


    Wait. You're imposing a requirement that you can't use a *loop*? And
    you're claiming this isn't homework?

    Please give me some real-life example of a situation in which a LOOP is
    forbidden.

    Paul Lalli
    Paul Lalli, Jan 24, 2006
    #2
    1. Advertising

  3. Todd W Guest

    <> wrote in message
    news:...
    > This is NOT homework!
    >
    > I want to comment out certain lines which immediately follow (as a
    > group) another line. I created a simple example:
    >
    > $_ = 'ZBCAACBABE';
    >
    > In English, for any group of A,B,or C's in any order, which follow a Z,
    > I want to preceed with ! . So in this example I want the regex to
    > produce:
    >
    > Z! B! C! A! A! C! B! A! BE
    >


    <snip OP's code>

    This may work for you:

    $ cat lbstrrep.pl
    use warnings;
    use strict;

    my $sequence = 'ZBCAACBABE';

    $sequence =~ s|Z([ABC]+)|'Z! ' . join('! ', split(//, $1))|eg;

    print( $sequence, "\n" );

    $ perl lbstrrep.pl
    Z! B! C! A! A! C! B! A! BE

    The /e modifier evaluates the replacement side of the regex as perl code and
    uses the result as the replacement string.

    Enjoy,

    trwww
    Todd W, Jan 24, 2006
    #3
  4. wrote:
    > This is NOT homework!
    >
    > I want to comment out certain lines which immediately follow (as a
    > group) another line. I created a simple example:
    >
    > $_ = 'ZBCAACBABE';
    >
    > In English, for any group of A,B,or C's in any order, which follow a Z,
    > I want to preceed with ! . So in this example I want the regex to
    > produce:
    >
    > Z! B! C! A! A! C! B! A! BE
    >
    > I tried ?= but I don't see a way to make that work. I thought
    >
    > s/(Z)(A|B|C)+/$1! $2/g;
    >
    > might have a chance but it produced
    >
    > 'Z! BE'
    >
    > I'm not sure I can explain that result.
    >
    > If your suggestion involves a loop please dont make it, I know plenty
    > of ways to do that.


    $ perl -le'
    $_ = q/ZBCAACBABE/;
    print;
    s{(?<=Z)([ABC]+)}{(my$x=$1)=~s<(?=.)><! >g;$x}eg;
    print;
    '
    ZBCAACBABE
    Z! B! C! A! A! C! B! A! BE



    John
    --
    use Perl;
    program
    fulfillment
    John W. Krahn, Jan 25, 2006
    #4
  5. Eric Bohlman Guest

    "Paul Lalli" <> wrote in news:1138134185.510690.251900
    @z14g2000cwz.googlegroups.com:

    > wrote:
    >> If your suggestion involves a loop please dont make it, I know plenty
    >> of ways to do that.

    >
    > Wait. You're imposing a requirement that you can't use a *loop*? And
    > you're claiming this isn't homework?
    >
    > Please give me some real-life example of a situation in which a LOOP is
    > forbidden.


    I can: if the regex needs to be read in as data.
    Eric Bohlman, Jan 25, 2006
    #5
  6. Guest

    Paul - turn down the flames, I don't like doing other's homework here
    and I wouldn't ask anyone else to do mine, that's all. No drama.. I'm
    just stumped is all.
    , Jan 25, 2006
    #6
  7. Guest

    > I'm not sure I can explain that result.
    >
    >Because your last parenthesized group has a + modifer. So when all is
    >said and done, $2 contains the *last* A, B, or C that it found. And
    >you replaced everything matched with $1, a !, and $2.


    Good explaination thanks! I sort of thought that the /g modifier would
    interact differently with the + though. I was obviously wrong!

    Spydox
    , Jan 25, 2006
    #7
  8. Guest

    I forbid it myself - as I said I know I can "loop" and solve this but I
    prefer a regex over a loop *almost* everytime. 99% of the time I can
    come up with a regex to solve anything that comes along, but this one
    has me stumped!

    Thanks everyone for the suggestions I'm trying them now. Particularly
    your ideas John- that's sort of a intimidating regex but it sure seemed
    to work! I'll have to cipher on that one a bit to comprehend it all

    :)

    Spydox
    , Jan 25, 2006
    #8
  9. Anno Siegel Guest

    <> wrote in comp.lang.perl.misc:
    > This is NOT homework!
    >
    > I want to comment out certain lines which immediately follow (as a
    > group) another line. I created a simple example:
    >
    > $_ = 'ZBCAACBABE';
    >
    > In English, for any group of A,B,or C's in any order, which follow a Z,
    > I want to preceed with ! . So in this example I want the regex to
    > produce:


    That's not a regex you want, it's a substitution operation. There's
    a difference.

    > Z! B! C! A! A! C! B! A! BE


    Here is one way to do it:

    s{Z([ABC]+)} {'Z' . join '', map "! $_", split //, $1}e;

    or, same principle but using a nested substitution:

    s{Z([ABC]+)} { my $x = $1; $x =~ s/(.)/! $1/g; "Z$x" }e;

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
    Anno Siegel, Jan 25, 2006
    #9
  10. Anno Siegel wrote:
    > <> wrote in comp.lang.perl.misc:
    >>This is NOT homework!
    >>
    >>I want to comment out certain lines which immediately follow (as a
    >>group) another line. I created a simple example:
    >>
    >>$_ = 'ZBCAACBABE';
    >>
    >>In English, for any group of A,B,or C's in any order, which follow a Z,
    >>I want to preceed with ! . So in this example I want the regex to
    >>produce:

    >
    > That's not a regex you want, it's a substitution operation. There's
    > a difference.
    >
    >> Z! B! C! A! A! C! B! A! BE

    >
    > Here is one way to do it:
    >
    > s{Z([ABC]+)} {'Z' . join '', map "! $_", split //, $1}e;


    Or more simply:

    s{(Z[ABC]+)} {join '! ', split //, $1}e;



    John
    --
    use Perl;
    program
    fulfillment
    John W. Krahn, Jan 25, 2006
    #10
  11. Anno Siegel Guest

    John W. Krahn <> wrote in comp.lang.perl.misc:
    > Anno Siegel wrote:
    > > <> wrote in comp.lang.perl.misc:
    > >>This is NOT homework!
    > >>
    > >>I want to comment out certain lines which immediately follow (as a
    > >>group) another line. I created a simple example:
    > >>
    > >>$_ = 'ZBCAACBABE';
    > >>
    > >>In English, for any group of A,B,or C's in any order, which follow a Z,
    > >>I want to preceed with ! . So in this example I want the regex to
    > >>produce:

    > >
    > > That's not a regex you want, it's a substitution operation. There's
    > > a difference.
    > >
    > >> Z! B! C! A! A! C! B! A! BE

    > >
    > > Here is one way to do it:
    > >
    > > s{Z([ABC]+)} {'Z' . join '', map "! $_", split //, $1}e;

    >
    > Or more simply:
    >
    > s{(Z[ABC]+)} {join '! ', split //, $1}e;


    Oh... good. I thought of join, but dismissed it (too quickly) because
    it doesn't prefix the first character. Very clever to exploit that
    behavior.

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
    Anno Siegel, Jan 25, 2006
    #11
  12. Guest


    > > > Here is one way to do it:
    > > >
    > > > s{Z([ABC]+)} {'Z' . join '', map "! $_", split //, $1}e;

    > >
    > > Or more simply:
    > >
    > > s{(Z[ABC]+)} {join '! ', split //, $1}e;

    >
    > Oh... good. I thought of join, but dismissed it (too quickly) because
    > it doesn't prefix the first character. Very clever to exploit that
    > behavior.
    >
    > Anno
    >


    I as well- I'm very impressed by this result. Thanks again John, nice
    work.

    I had a reply in email from Xicheng that suggested:

    perl -le '$_ = "ZBCAACBABE";s/(.)(?=[ABC])/$1! /g;print'
    ==you get==
    Z! B! C! A! A! C! B! A! BE

    which I thought was REALLY SLICK.. However, I needed it to check for
    "Z", not (.), so I replaced it with:

    perl -le '$_ = "ZBCAACBABE";s/(Z))(?=[ABC])/$1! /g;print'
    (which BROKE IT for some reason):
    Z! BCAACBABE

    Anyhow- I'm not futzing around with s/(.)(?=[ABC])/$1! /g trying to get
    it to work correctly. I think Xicheng is onto something! I had
    previously tried ?=(ABC) but not the character class.

    Have a good weekend, thanks everyone for chiming in. I will comment
    that "context-switching ops", that is using s/// to change everything
    between A and B seems like a difficult thing to do. Maybe s/// isn't
    the best tool for that...

    Have a good weekend!
    , Jan 27, 2006
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?SmViQnVzaGVsbA==?=

    Is ASP Validator Regex Engine Same As VS2003 Find Regex Engine?

    =?Utf-8?B?SmViQnVzaGVsbA==?=, Oct 22, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    690
    =?Utf-8?B?SmViQnVzaGVsbA==?=
    Oct 22, 2005
  2. Rick Venter

    perl regex to java regex

    Rick Venter, Oct 29, 2003, in forum: Java
    Replies:
    5
    Views:
    1,607
    Ant...
    Nov 6, 2003
  3. Replies:
    2
    Views:
    589
  4. Xah Lee
    Replies:
    1
    Views:
    931
    Ilias Lazaridis
    Sep 22, 2006
  5. Replies:
    3
    Views:
    732
    Reedick, Andrew
    Jul 1, 2008
Loading...

Share This Page