Stupid perl regexp question

G

G Klinedinst

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
 
U

Uri Guttman

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
 
D

D Borland

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

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

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

Dagmar
 
D

Darren Dunham

G Klinedinst said:
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.
 
J

Jeff 'japhy' Pinyan

[posted & mailed]

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.
 
G

G Klinedinst

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
 
B

Barry Kimelman

[This followup was posted to comp.lang.perl.misc]

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top