Stupid perl regexp question

Discussion in 'Perl Misc' started by G Klinedinst, Sep 22, 2003.

  1. G Klinedinst

    G Klinedinst Guest

    This is a really stupid regexp question but can someone please explain
    to me why this doesn't work:

    if( m/\/{1}/ ) { print $_; }

    I want to match only those lines which contain 1 and only 1 "/"
    character. My understanding is that a forward slash needs escaped or
    else it would signal the end of the regexp, the {1} indicates to match
    one and only one time. I have seen examples such as:

    $string =~ m/^\S{1,8}\.\S{0,3}/;

    which clearly show the syntax of both escaping and repetition and I
    can't see for the life of me how mine is different, except that I
    don't care about the pattern matching at the beginning of the string.

    Output is returning lines that have 1 or more "/" chars. TIA for any
    help. BTW, please do not reply with suggestions to use grep, or
    sed/awk, or python, or C, or Lisp, or Smalltalk or any other languages
    or techniques. I want to use Perl for what I am doing.

    G. Klinedinst
    G Klinedinst, Sep 22, 2003
    #1
    1. Advertising

  2. G Klinedinst

    Uri Guttman Guest

    >>>>> "GK" == G Klinedinst <> writes:

    GK> help. BTW, please do not reply with suggestions to use grep, or
    GK> sed/awk, or python, or C, or Lisp, or Smalltalk or any other
    GK> languages or techniques. I want to use Perl for what I am doing.

    i doubt anyone here would suggest anything but perl for what you are
    trying to do.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Damian Conway Class in Boston - Sept 2003 -- http://www.stemsystems.com/class
    Uri Guttman, Sep 22, 2003
    #2
    1. Advertising

  3. G Klinedinst

    D Borland Guest

    you could try... (note, not tested)

    if (/\/(.*)/) {
    print $_ unless ($1 =~ /\//);
    }

    i'm sure someone here could show you something neater though :)

    Dagmar


    "G Klinedinst" <> wrote in message
    news:...
    > This is a really stupid regexp question but can someone please explain
    > to me why this doesn't work:
    >
    > if( m/\/{1}/ ) { print $_; }
    >
    > I want to match only those lines which contain 1 and only 1 "/"
    > character. My understanding is that a forward slash needs escaped or
    > else it would signal the end of the regexp, the {1} indicates to match
    > one and only one time. I have seen examples such as:
    >
    > $string =~ m/^\S{1,8}\.\S{0,3}/;
    >
    > which clearly show the syntax of both escaping and repetition and I
    > can't see for the life of me how mine is different, except that I
    > don't care about the pattern matching at the beginning of the string.
    >
    > Output is returning lines that have 1 or more "/" chars. TIA for any
    > help. BTW, please do not reply with suggestions to use grep, or
    > sed/awk, or python, or C, or Lisp, or Smalltalk or any other languages
    > or techniques. I want to use Perl for what I am doing.
    >
    > G. Klinedinst
    D Borland, Sep 22, 2003
    #3
  4. G Klinedinst <> wrote:
    > This is a really stupid regexp question but can someone please explain
    > to me why this doesn't work:


    > if( m/\/{1}/ ) { print $_; }


    It works, it's just not what you want to happen... :)

    Since you haven't anchored anything, that will match any string which
    has one slash in it. Not "one and only one", just "one".

    > I want to match only those lines which contain 1 and only 1 "/"
    > character. My understanding is that a forward slash needs escaped or
    > else it would signal the end of the regexp, the {1} indicates to match
    > one and only one time. I have seen examples such as:


    > $string =~ m/^\S{1,8}\.\S{0,3}/;


    In general the regex /x{1,5}/ is equivalent to /x/, because if there are
    5, there's at least 1, and /x/ will match.

    They are different only when
    1) you are caputuring data or
    2) you are specifying data on both sides of the expression

    In your example, the \S{1,8} *must* be bounded on the front by the
    beginning of the string, and on the rear by a dot (\.). If the front of
    string specification weren't there, the {1,8} expression would be no
    more useful than a single \S, because 1, 8, or a thousand characters in
    the string would still allow a match.

    Another way to say "one and only one slash", is "starts with any number
    of non-slash characters, has a slash, and ends with any number of
    non-slash characters.

    > I want to match only those lines which contain 1 and only 1 "/"
    > character. My understanding is that a forward slash needs escaped or
    > else it would signal the end of the regexp, the {1} indicates to match
    > one and only one time. I have seen examples such as:


    You can use different characters to delmit the regex. When you want to
    match forward slashes, that can come in handy.

    > which clearly show the syntax of both escaping and repetition and I
    > can't see for the life of me how mine is different, except that I
    > don't care about the pattern matching at the beginning of the string.


    Lets try constructing a regex for my restatement of your target string,
    using an alternate delimiter, and a character class. [^/] will
    represent all characters other than a forward slash.

    m!^[^/]*/[^/]*$!

    You could probably do the same thing with negative lookahead and
    lookbehind, but I'm less familiar with those techniques.

    --
    Darren Dunham
    Unix System Administrator Taos - The SysAdmin Company
    Got some Dr Pepper? San Francisco, CA bay area
    < This line left intentionally blank to confuse you. >
    Darren Dunham, Sep 23, 2003
    #4
  5. [posted & mailed]

    On 22 Sep 2003, G Klinedinst wrote:

    >This is a really stupid regexp question but can someone please explain
    >to me why this doesn't work:
    >
    >if( m/\/{1}/ ) { print $_; }
    >
    >I want to match only those lines which contain 1 and only 1 "/"


    That regex doesn't say "does $_ have ONLY one / in it?", it says "does $_
    have a / in it?". To get what you want, you'll need to use either

    print if tr!/!! == 1;

    which uses the tr/// operator (which returns the count of the characters
    it matches in your string, so "alphabet" =~ tr/ab// would return 3, for
    the a, a, and b it finds), or else

    print if m{^[^/]*/[^/]*$};

    which matches a string containing zero or more non-slashes, followed by a
    slash, followed by zero or more non-slashes, and anchored at the beginning
    and end of the string.

    --
    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, Sep 23, 2003
    #5
  6. G Klinedinst

    G Klinedinst Guest

    Thank you all for your help. I have learned a number of different ways
    to do this but more importantly I think I understand why is wasn't
    working in the first place.
    It sounds like the {n} operator means to look for n number of
    consecutive "/" strings which can occur any number of times in the
    string, instead of what I had imagined it meant.
    Changing the delimeter helps a bunch, thanks to all who made that
    suggestion. Also that tr/// trick where it returns the number of
    characters translated is great!


    G. Klinedinst
    G Klinedinst, Sep 23, 2003
    #6
  7. [This followup was posted to comp.lang.perl.misc]

    In article <>,
    says...
    > This is a really stupid regexp question but can someone please explain
    > to me why this doesn't work:
    >
    > if( m/\/{1}/ ) { print $_; }
    >
    > I want to match only those lines which contain 1 and only 1 "/"
    > character. My understanding is that a forward slash needs escaped or
    > else it would signal the end of the regexp, the {1} indicates to match
    > one and only one time. I have seen examples such as:
    >
    > $string =~ m/^\S{1,8}\.\S{0,3}/;
    >
    > which clearly show the syntax of both escaping and repetition and I
    > can't see for the life of me how mine is different, except that I
    > don't care about the pattern matching at the beginning of the string.
    >
    > Output is returning lines that have 1 or more "/" chars. TIA for any
    > help. BTW, please do not reply with suggestions to use grep, or
    > sed/awk, or python, or C, or Lisp, or Smalltalk or any other languages
    > or techniques. I want to use Perl for what I am doing.
    >
    > G. Klinedinst
    >


    Your regexp will match any string that contains 1 consecutive "/" at any
    point in the string. Therefor if you have 2 "/" at different points in
    the string your pattern will still produce a match.

    And if i have a choice when it comes to text processing and pattern
    matching I will always choose Perl.
    Barry Kimelman, Sep 24, 2003
    #7
    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. Brandon McCombs
    Replies:
    4
    Views:
    498
    Richard Wheeldon
    Aug 28, 2006
  2. rincewind

    stupid, STUPID question!

    rincewind, Apr 19, 2009, in forum: HTML
    Replies:
    25
    Views:
    1,007
  3. Joao Silva
    Replies:
    16
    Views:
    337
    7stud --
    Aug 21, 2009
  4. Steve Linberg

    stupid regexp question

    Steve Linberg, Apr 19, 2004, in forum: Perl Misc
    Replies:
    2
    Views:
    83
    Steve Linberg
    Apr 19, 2004
  5. Daedalus
    Replies:
    14
    Views:
    171
    Daedalus
    Jun 25, 2004
Loading...

Share This Page