variable-width negative look-behind emulation

Ask a Question related to PERL Miscellaneous, Design and Development.

  1. #1

    Default variable-width negative look-behind emulation

    I was playing with variable-width negative look-behind emulation and
    worked out this regexp that supports assertions about substrings of
    the pre-match:

    /^.*(??{ index($&,"foo") == -1 ? "" : "(?!)" })bar/

    That matches "bar" if it is not preceded at any point by "foo". I know
    that can be achieved by reverse + negative look-ahead but this has to
    be considered an exercise (that comes from a question in freenode#perl
    that required a single regexp to solve the problem).

    I tried a few tricks to extend that to patterns as

    /^.*(??{ $& =~ m,fo+, ? "(?!)" : "" })bar/

    or

    /^.*(?{ local $m = $& })(??{ $m =~ m,fo+, ? "(?!)" : "" })bar/

    and the like, but I got segmentation faults (maybe that hits some
    corner of the documented experimentalness of that stuff). Looks like
    the problem comes from nesting m//, but that's a guess.

    Any comments?

    -- fxn
    Xavier Noria Guest

  2. Similar Questions and Discussions

    1. variable width line
      Can you make a line drawn with the pen tool narrow at one end and fatter at the other so it goes from say 1 pt to 4 pt and gets thicker?
    2. fixed width variable
      Greetings, I have been searching for a way to do this and have not had any luck. I am using localtime() to determine the day of the month. I...
    3. How did this variable become negative?
      On Mon, Aug 25, 2003 at 10:54:46AM +0900, Philip Mak wrote: As you point out, your code is not threads-safe Consider the following scenario: *...
    4. help me - variable width
      i have designed a site fully in flash mx but i want the site to be appear the full size of the browser window. i have heard that you can do this by...
    5. sql*loader fixed width column / variable length record
      im trying to figure this out. i have a datafile with the following records tony sometext 120121122 mark sometext2 120 ethan ...
  3. #2

    Default Re: variable-width negative look-behind emulation

    On 13 Sep 2003, Xavier Noria wrote:
    >I was playing with variable-width negative look-behind emulation and
    >worked out this regexp that supports assertions about substrings of
    >the pre-match:
    >
    > /^.*(??{ index($&,"foo") == -1 ? "" : "(?!)" })bar/
    >
    >That matches "bar" if it is not preceded at any point by "foo". I know
    >that can be achieved by reverse + negative look-ahead but this has to
    >be considered an exercise (that comes from a question in freenode#perl
    >that required a single regexp to solve the problem).
    You could use

    /^(?:[^f]*|f+(?!f|oo))*bar/;

    --
    Jeff Pinyan RPI Acacia Brother #734 2003 Rush Chairman
    "And I vos head of Gestapo for ten | Michael Palin (as Heinrich Bimmler)
    years. Ah! Five years! Nein! No! | in: The North Minehead Bye-Election
    Oh. Was NOT head of Gestapo AT ALL!" | (Monty Python's Flying Circus)

    Jeff 'japhy' Pinyan Guest

  4. #3

    Default Re: variable-width negative look-behind emulation

    Jeff 'japhy' Pinyan <pinyaj@rpi.edu> wrote in message news:<Pine.SGI.3.96.1030913220055.85446A-100000@vcmr-64.server.rpi.edu>...
    > On 13 Sep 2003, Xavier Noria wrote:
    >
    > >I was playing with variable-width negative look-behind emulation and
    > >worked out this regexp that supports assertions about substrings of
    > >the pre-match:
    > >
    > > /^.*(??{ index($&,"foo") == -1 ? "" : "(?!)" })bar/
    > >
    > >That matches "bar" if it is not preceded at any point by "foo". I know
    > >that can be achieved by reverse + negative look-ahead but this has to
    > >be considered an exercise (that comes from a question in freenode#perl
    > >that required a single regexp to solve the problem).
    >
    > You could use
    >
    > /^(?:[^f]*|f+(?!f|oo))*bar/;
    Ah, better, thank you.

    Maybe we could take benefit of atomic grouping here? Like this

    /^ (?> [^f] | f(?!oo) )*? bar/x

    or even better maybe this way

    /^(?> (?!foo). )*? bar/x

    which has been suggested by Iain Truskett right now on freenode#regex.

    -- fxn
    Xavier Noria Guest

  5. #4

    Default Re: variable-width negative look-behind emulation

    On 14 Sep 2003, Xavier Noria wrote:
    >> > /^.*(??{ index($&,"foo") == -1 ? "" : "(?!)" })bar/
    >>
    >> /^(?:[^f]*|f+(?!f|oo))*bar/;
    >
    >Ah, better, thank you.
    >
    >Maybe we could take benefit of atomic grouping here? Like this
    >
    > /^ (?> [^f] | f(?!oo) )*? bar/x
    I'd rather see [^f]+. (That should have been [^f]+ in my regex.)
    >or even better maybe this way
    >
    > /^(?> (?!foo). )*? bar/x
    That crawls one character at a time, and the (?>) shouldn't be needed.

    --
    Jeff Pinyan RPI Acacia Brother #734 2003 Rush Chairman
    "And I vos head of Gestapo for ten | Michael Palin (as Heinrich Bimmler)
    years. Ah! Five years! Nein! No! | in: The North Minehead Bye-Election
    Oh. Was NOT head of Gestapo AT ALL!" | (Monty Python's Flying Circus)

    Jeff 'japhy' Pinyan Guest

  6. #5

    Default Re: variable-width negative look-behind emulation

    Jeff 'japhy' Pinyan <pinyaj@rpi.edu> wrote in message news:<Pine.SGI.3.96.1030914095011.349954A-100000@vcmr-64.server.rpi.edu>...
    > On 14 Sep 2003, Xavier Noria wrote:
    >
    > >> > /^.*(??{ index($&,"foo") == -1 ? "" : "(?!)" })bar/
    > >>
    > >> /^(?:[^f]*|f+(?!f|oo))*bar/;
    > >
    > >Ah, better, thank you.
    > >
    > >Maybe we could take benefit of atomic grouping here? Like this
    > >
    > > /^ (?> [^f] | f(?!oo) )*? bar/x
    >
    > I'd rather see [^f]+. (That should have been [^f]+ in my regex.)
    The problem there is that it seems we loose the states corresponding
    to [^f]+, which in spite of the outer *? eats too much and would need
    to backtrack:

    % perl -wle 'print 1 if "xbar" =~ /^(?>[^f]+|f(?!oo))*?bar/'
    % perl -wle 'print 1 if "xbar" =~ /^(?>[^f]|f(?!oo))*?bar/'
    1

    But [^f]+ is fine if we don't use atomic grouping:

    % perl -wle 'print 1 if "xbar" =~ /^(?:[^f]+|f(?!oo))*?bar/'
    1
    > >or even better maybe this way
    > >
    > > /^(?> (?!foo). )*? bar/x
    >
    > That crawls one character at a time, and the (?>) shouldn't be needed.
    Yeah, it's there just to indicate to the engine it can forget about
    the states. We either match in one shot or fail.

    -- fxn
    Xavier Noria Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139