regex question

Discussion in 'Perl Misc' started by John Black, Jun 20, 2013.

  1. John Black

    John Black Guest

    How do I write a regex that will match on

    string

    but not

    string_

    I want it to match if it detects string followed by anything but an underscore including if
    string is at the end of the line or if its followed by a space or whatever. Right now I'm
    essentially doing two checks: matches string and does not match string_ but I am sure there
    must be a more elegant way to do it? Thanks.

    John Black
     
    John Black, Jun 20, 2013
    #1
    1. Advertising

  2. John Black <> writes:
    > How do I write a regex that will match on
    >
    > string
    >
    > but not
    >
    > string_
    >
    > I want it to match if it detects string followed by anything but an underscore including if
    > string is at the end of the line or if its followed by a space or
    > whatever.


    /string(?!_)/
     
    Rainer Weikusat, Jun 20, 2013
    #2
    1. Advertising

  3. John Black

    Jim Gibson Guest

    In article <>, Rainer
    Weikusat <> wrote:

    > John Black <> writes:
    > > How do I write a regex that will match on
    > >
    > > string
    > >
    > > but not
    > >
    > > string_
    > >
    > > I want it to match if it detects string followed by anything but an
    > > underscore including if
    > > string is at the end of the line or if its followed by a space or
    > > whatever.

    >
    > /string(?!_)/


    To elucidate: that is a "zero-width negative look-ahead assertion". For
    more information, see 'perldoc perlre' and search or scroll to the
    section on "Extended Patterns", specifically the subsection on
    "Look-Around Assertions".

    --
    Jim Gibson
     
    Jim Gibson, Jun 21, 2013
    #3
  4. John Black

    John Black Guest

    In article <210620130850374203%>, says...
    >
    > In article <>, Rainer
    > Weikusat <> wrote:
    >
    > > John Black <> writes:
    > > > How do I write a regex that will match on
    > > >
    > > > string
    > > >
    > > > but not
    > > >
    > > > string_
    > > >
    > > > I want it to match if it detects string followed by anything but an
    > > > underscore including if
    > > > string is at the end of the line or if its followed by a space or
    > > > whatever.

    > >
    > > /string(?!_)/

    >
    > To elucidate: that is a "zero-width negative look-ahead assertion". For
    > more information, see 'perldoc perlre' and search or scroll to the
    > section on "Extended Patterns", specifically the subsection on
    > "Look-Around Assertions".


    This is great. Thanks to both of you. It does work for my example but I tried to apply it
    to a different example and its not working. I want to match on some pattern that is not
    followed by some other string later but not necessarily immediately following like my
    original example.

    I tried /pattern1.*(?!string)/

    but this seems to match pattern1 even if "string" comes later somewhere on the line.

    John Black
     
    John Black, Jun 21, 2013
    #4
  5. On 6/21/2013 12:45 PM, John Black wrote:
    > In article <210620130850374203%>, says...
    >>
    >> [...]

    >
    > This is great. Thanks to both of you. It does work for my example but I tried to apply it
    > to a different example and its not working. I want to match on some pattern that is not
    > followed by some other string later but not necessarily immediately following like my
    > original example.
    >
    > I tried /pattern1.*(?!string)/
    >
    > but this seems to match pattern1 even if "string" comes later somewhere on the line.
    >


    Another alternative to lookaheads is the /p switch which effectively
    partitions a successful match into pre-match, match, and post-match:

    if ( "foo bar" =~ /foo/p and ${^POSTMATCH} !~ /bar/ ) ...

    So, ${^PREMATCH} is "", ${^MATCH} is"foo", and ${^POSTMATCH} is " bar"

    P.S. ( "p" in /p doesn't mean "partition" but it's still an easy way to
    remember what happens. See perlre ).

    --
    Charles DeRykus
     
    Charles DeRykus, Jun 22, 2013
    #5
  6. John Black

    John Black Guest

    In article <kq3qnu$8m0$>, says...
    >
    > On 6/21/2013 12:45 PM, John Black wrote:
    > > In article <210620130850374203%>, says...
    > >>
    > >> [...]

    > >
    > > This is great. Thanks to both of you. It does work for my example but I tried to apply it
    > > to a different example and its not working. I want to match on some pattern that is not
    > > followed by some other string later but not necessarily immediately following like my
    > > original example.
    > >
    > > I tried /pattern1.*(?!string)/
    > >
    > > but this seems to match pattern1 even if "string" comes later somewhere on the line.
    > >

    >
    > Another alternative to lookaheads is the /p switch which effectively
    > partitions a successful match into pre-match, match, and post-match:
    >
    > if ( "foo bar" =~ /foo/p and ${^POSTMATCH} !~ /bar/ ) ...
    >
    > So, ${^PREMATCH} is "", ${^MATCH} is"foo", and ${^POSTMATCH} is " bar"
    >
    > P.S. ( "p" in /p doesn't mean "partition" but it's still an easy way to
    > remember what happens. See perlre ).


    Charles, thanks. I like it. Its actually more readable than the negative lookahead syntax.

    John Black
     
    John Black, Jun 25, 2013
    #6
  7. John Black

    John Black Guest

    In article <>, says...
    >
    > Quoth John Black <>:
    > >
    > > This is great. Thanks to both of you. It does work for my example but
    > > I tried to apply it
    > > to a different example and its not working. I want to match on some
    > > pattern that is not
    > > followed by some other string later but not necessarily immediately
    > > following like my
    > > original example.
    > >
    > > I tried /pattern1.*(?!string)/
    > >
    > > but this seems to match pattern1 even if "string" comes later somewhere
    > > on the line.

    >
    > Yes. Think a bit about how it matches. If you match (say)
    >
    > "foo bar" =~ /foo.*(?!bar)/
    >
    > then first the 'foo' matches the 'foo', then the .* matches the ' bar',
    > then perl tries to match /bar/ at that point. It doesn't match (we're at
    > the end of the string), so the (?!) succeeds, and the whole match
    > succeeds.
    >
    > Running a match under 'use re "debug";' might help you to understand
    > what's going on, though it tends to produce so much output it takes a
    > bit of practice to sort through it.
    >
    > You want to assert 'starting immediately after the 'foo', it must not be
    > possible to match any amount of text followed by 'bar''. That is,
    >
    > /foo(?!.*bar)/
    >
    > with the .* inside the (?!). (You may also want /s.)


    Ben, thanks. This makes sense but I'm not sure where I would want the /s or why?

    John Black
     
    John Black, Jun 25, 2013
    #7
  8. John Black

    John Black Guest

    In article <>, says...
    >
    > Quoth John Black <>:
    > > In article <>, says...
    > > >
    > > > You want to assert 'starting immediately after the 'foo', it must not be
    > > > possible to match any amount of text followed by 'bar''. That is,
    > > >
    > > > /foo(?!.*bar)/
    > > >
    > > > with the .* inside the (?!). (You may also want /s.)

    > >
    > > Ben, thanks. This makes sense but I'm not sure where I would want the
    > > /s or why?

    >
    > Read the section on m// in perlop. /s makes . match newline, which it
    > otherwise doesn't.


    Ah yes. I was confused because for some reason, I saw your /s as \s. Thanks.

    John Black
     
    John Black, Jun 25, 2013
    #8
    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:
    724
    =?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,649
    Ant...
    Nov 6, 2003
  3. Replies:
    2
    Views:
    611
  4. Xah Lee
    Replies:
    1
    Views:
    954
    Ilias Lazaridis
    Sep 22, 2006
  5. Replies:
    3
    Views:
    794
    Reedick, Andrew
    Jul 1, 2008
Loading...

Share This Page