I think an assertion might do this?

Discussion in 'Perl Misc' started by Mr P, Aug 4, 2010.

  1. Mr P

    Mr P Guest

    Hey Perlistas...

    I wanted to replace any and all multiple sequential EOLs with a single
    one. This worked nicely:

    (a) s/(\n)\n+/$1/g;

    But thinking abot it some more. it occurred to me that these wouldn't
    quite work

    (b) s/(\n)\n/$1/g;
    (c) s/\n(\n)/$1/g;
    (d) s/\n\n/\n/g;

    because even though they are greedy, they don't retrace. And
    predictably they didn't work.

    I've never really used assertions, at least not enough to be familiar
    with them. I guess this would be a positive look-behind to force the
    engine to retrace?

    Can someone offer an example please where I can use something like s/
    (\n)\n/$1/g; with an assertion to do what (a) does? It would be
    instructional for me to see this example.

    Thanks
     
    Mr P, Aug 4, 2010
    #1
    1. Advertising

  2. Mr P

    Justin C Guest

    On 2010-08-04, Mr P <> wrote:
    > Hey Perlistas...
    >
    > I wanted to replace any and all multiple sequential EOLs with a single
    > one. This worked nicely:
    >
    > (a) s/(\n)\n+/$1/g;
    >
    > But thinking abot it some more. it occurred to me that these wouldn't
    > quite work
    >
    > (b) s/(\n)\n/$1/g;
    > (c) s/\n(\n)/$1/g;
    > (d) s/\n\n/\n/g;
    >
    > because even though they are greedy, they don't retrace. And
    > predictably they didn't work.
    >
    > I've never really used assertions, at least not enough to be familiar
    > with them. I guess this would be a positive look-behind to force the
    > engine to retrace?
    >
    > Can someone offer an example please where I can use something like s/
    > (\n)\n/$1/g; with an assertion to do what (a) does? It would be
    > instructional for me to see this example.


    I would use s/(\n){2,}/\n/g that's \n two or more times.

    Justin.

    --
    Justin C, by the sea.
     
    Justin C, Aug 4, 2010
    #2
    1. Advertising

  3. On 04.08.2010 15:02, Mr P wrote:
    > Hey Perlistas...
    >
    > I wanted to replace any and all multiple sequential EOLs with a single
    > one. This worked nicely:
    >
    > (a) s/(\n)\n+/$1/g;
    >
    > Can someone offer an example please where I can use something like s/
    > (\n)\n/$1/g; with an assertion to do what (a) does? It would be
    > instructional for me to see this example.


    Are you looking for this?
    s/(\n)(?=\n)//g; # global remove \n if another \n follows

    Other than that, sometimes you also see something like this:
    1 while s#\n\n#\n#;

    Wolf
     
    Wolf Behrenhoff, Aug 4, 2010
    #3
  4. Mr P

    Uri Guttman Guest

    >>>>> "JC" == Justin C <> writes:

    JC> I would use s/(\n){2,}/\n/g that's \n two or more times.

    no need for the () there as you don't use the grab. and tad's tr/// is
    the best solution anyhow.

    uri

    --
    Uri Guttman ------ -------- http://www.sysarch.com --
    ----- Perl Code Review , Architecture, Development, Training, Support ------
    --------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
     
    Uri Guttman, Aug 4, 2010
    #4
  5. Mr P

    C.DeRykus Guest

    On Aug 4, 6:02 am, Mr P <> wrote:
    > Hey Perlistas...
    >
    > I wanted to replace any and all multiple sequential EOLs with a single
    > one. This worked nicely:
    >
    > (a)  s/(\n)\n+/$1/g;
    >
    > But thinking abot it some more. it occurred to me that these wouldn't
    > quite work
    >
    > (b) s/(\n)\n/$1/g;
    > (c) s/\n(\n)/$1/g;
    > (d) s/\n\n/\n/g;
    >
    > because even though they are greedy, they don't retrace. And
    > predictably they didn't work.


    The /g switch applies the substitution globally
    but greedy applies only to quantifiers such as *,
    + or {m,n}, etc.

    The reason /g fails is that the engine matches and
    substitutes consecutive pairs of \n's but, a final
    trailing \n in any odd number of consecutive \n's
    doesn't get replaced.


    >
    > I've never really used assertions, at least not enough to be familiar
    > with them. I guess this would be a positive look-behind to force the
    > engine to retrace?


    It's easier IMO to think of this with the positive
    look-ahead assertion solution that was shown. A
    positive look-behind would work too though:

    s/ (?<=\n) \n//gx;


    >
    > Can someone offer an example please where I can use something like s/
    > (\n)\n/$1/g; with an assertion to do what (a) does? It would be
    > instructional for me to see this example.
    >


    No, the look-ahead/behind assertions are zero length
    so with something such as you've shown plus a look-
    ahead/behind assertion, you'd be capturing and then
    just replacing only the capture. The target wouldn't
    be changed at all.


    --
    Charles DeRykus
     
    C.DeRykus, Aug 4, 2010
    #5
  6. Mr P

    Mr P Guest

    On Aug 4, 9:59 am, Tad McClellan <> wrote:
    > Mr P <> wrote:
    > > I wanted to replace any and all multiple sequential EOLs with a single
    > > one. This worked nicely:

    >
    > > (a)  s/(\n)\n+/$1/g;

    >
    > You don't need regular expressions to do that:
    >
    >     tr/\n/\n/s;
    > or
    >     tr/\n//s;
    >

    That's quite a surprising solution to me as I would not have thought
    of tr// - I will monkey with it thanks.. I always thought of tr// as a
    1:1 mapping which is not what this is, so it seems un-natrual.

    >
    > I don't see how assertions can help with this problem...


    It seemed like a natural solution to me.

    start with /n/n/n
    s/(\n)\n/$1/ now you have \n\n.
    Which would MATCH again, IF the engine started at the scalar
    beginning (hence my use of the word RETRACE, and my thought that this
    was a LOOK-Behind case)..
    >


    As far as greed and quantifiers, requiring quantifiers makes no sense.
    If I dont have the /g switch, the regex operates ONE TIME on the
    scalar. If /g (regardless of quantifiers) it operates on the entire
    scalar, as many times as it matches. And if it reset to the beginning
    of the scalar AFTER each match, it would even work the same way as s/\n
    \n*/\n/;

    >

    THanks.
    > --
    > Tad McClellan
    > email: perl -le "print scalar reverse qq/moc.liamg\100cm.j.dat/"
    > The above message is a Usenet post.
    > I don't recall having given anyone permission to use it on a Web site.
     
    Mr P, Aug 4, 2010
    #6
  7. Mr P

    Uri Guttman Guest

    >>>>> "P" == P <> writes:

    P> On Aug 4, 9:59 am, Tad McClellan <> wrote:
    >> Mr P <> wrote:
    >> > I wanted to replace any and all multiple sequential EOLs with a single
    >> > one. This worked nicely:

    >>
    >> > (a)  s/(\n)\n+/$1/g;

    >>
    >> You don't need regular expressions to do that:
    >>
    >>     tr/\n/\n/s;
    >> or
    >>     tr/\n//s;
    >>

    P> That's quite a surprising solution to me as I would not have thought
    P> of tr// - I will monkey with it thanks.. I always thought of tr// as a
    P> 1:1 mapping which is not what this is, so it seems un-natrual.

    no, it seems very natural if you rtfm! it can also delete chars with the
    /d option. both /s and /d are very useful and much faster than the
    equivilent s/// ops.

    P> As far as greed and quantifiers, requiring quantifiers makes no sense.
    P> If I dont have the /g switch, the regex operates ONE TIME on the
    P> scalar. If /g (regardless of quantifiers) it operates on the entire
    P> scalar, as many times as it matches. And if it reset to the beginning
    P> of the scalar AFTER each match, it would even work the same way as s/\n
    P> \n*/\n/;

    you don't get quantifiers then. they modify a single regex thing to
    their left. s/\n+/\n/g is the simplest way to get what you want with
    s///. note no grabbing is needed since you know the replacement will
    just be a single \n. there are several variants with assertions i won't
    go into.

    uri

    --
    Uri Guttman ------ -------- http://www.sysarch.com --
    ----- Perl Code Review , Architecture, Development, Training, Support ------
    --------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
     
    Uri Guttman, Aug 4, 2010
    #7
  8. Mr P

    Jim Gibson Guest

    In article <>, Uri Guttman
    <> wrote:

    > >>>>> "P" == P <> writes:

    >
    > P> On Aug 4, 9:59 am, Tad McClellan <> wrote:
    > >> Mr P <> wrote:
    > >> > I wanted to replace any and all multiple sequential EOLs with a single
    > >> > one. This worked nicely:
    > >>
    > >> > (a)  s/(\n)\n+/$1/g;
    > >>
    > >> You don't need regular expressions to do that:
    > >>
    > >>     tr/\n/\n/s;
    > >> or
    > >>     tr/\n//s;
    > >>

    > P> That's quite a surprising solution to me as I would not have thought
    > P> of tr// - I will monkey with it thanks.. I always thought of tr// as a
    > P> 1:1 mapping which is not what this is, so it seems un-natrual.
    >
    > no, it seems very natural if you rtfm! it can also delete chars with the
    > /d option. both /s and /d are very useful and much faster than the
    > equivilent s/// ops.


    Sure, but poor old tr is a second-class citizen when it comes to
    documentation. Look at 'perldoc -f tr'. Then please explain how tr ( or
    s/// for that matter) is a "quote-like operator". You have to remember
    to search for 'Transliterates' to get to the documentation for tr :(

    I would extract the section in 'perldoc perlop' and put it in 'perldoc
    -f tr'.

    --
    Jim Gibson
     
    Jim Gibson, Aug 4, 2010
    #8
  9. Mr P

    Jim Gibson Guest

    In article
    <>, Mr
    P <> wrote:

    > On Aug 4, 9:59 am, Tad McClellan <> wrote:
    > > Mr P <> wrote:
    > > > I wanted to replace any and all multiple sequential EOLs with a single
    > > > one. This worked nicely:

    > >
    > > > (a)  s/(\n)\n+/$1/g;

    > >
    > > You don't need regular expressions to do that:
    > >
    > >     tr/\n/\n/s;
    > > or
    > >     tr/\n//s;
    > >

    > That's quite a surprising solution to me as I would not have thought
    > of tr// - I will monkey with it thanks.. I always thought of tr// as a
    > 1:1 mapping which is not what this is, so it seems un-natrual.


    Yes, tr can be used as n:1 or 1:0 mappings, not just 1:1.
    >
    > >
    > > I don't see how assertions can help with this problem...

    >
    > It seemed like a natural solution to me.
    >
    > start with /n/n/n
    > s/(\n)\n/$1/ now you have \n\n.
    > Which would MATCH again, IF the engine started at the scalar
    > beginning (hence my use of the word RETRACE, and my thought that this
    > was a LOOK-Behind case)..


    If you want to redo a regular expression from the beginning of the
    string and keep repeating it until it fails to match, put it in a while
    loop:

    while( s/(\n)\n/$1/g ) {
    ;
    }

    However, you have already been given the simplest solution using
    regexes:

    s/\n{2,}/\n/g;

    which fixes your string in one pass, as do all the look-around
    variations.

    --
    Jim Gibson
     
    Jim Gibson, Aug 4, 2010
    #9
  10. Mr P

    Uri Guttman Guest

    >>>>> "JG" == Jim Gibson <> writes:

    JG> Sure, but poor old tr is a second-class citizen when it comes to
    JG> documentation. Look at 'perldoc -f tr'. Then please explain how tr ( or
    JG> s/// for that matter) is a "quote-like operator". You have to remember
    JG> to search for 'Transliterates' to get to the documentation for tr :(

    tr/// is quote like because it can take alternate delimiters like all
    the quote ops.

    JG> I would extract the section in 'perldoc perlop' and put it in 'perldoc
    JG> -f tr'.

    and it is an operator not a function as it has operator syntax. you can
    call it with () which all functions can be called with.

    tr should be more well known and taught as it can do things s/// can't
    do and most things it does is much faster. they are only related because
    they are quotelike and share the use of =~.

    uri

    --
    Uri Guttman ------ -------- http://www.sysarch.com --
    ----- Perl Code Review , Architecture, Development, Training, Support ------
    --------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
     
    Uri Guttman, Aug 5, 2010
    #10
    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. Marek Ponca

    Enumerated Type in assertion ?

    Marek Ponca, Jan 10, 2005, in forum: VHDL
    Replies:
    2
    Views:
    3,276
    Jonathan Bromley
    Jan 10, 2005
  2. Replies:
    0
    Views:
    626
  3. Replies:
    1
    Views:
    889
    Jack Klein
    Apr 13, 2005
  4. Replies:
    17
    Views:
    154
    Tim Greer
    Oct 22, 2008
  5. David Mark
    Replies:
    17
    Views:
    249
    David Mark
    Mar 23, 2010
Loading...

Share This Page