Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister

Regex Validation

by jimb (Novice)
on Jul 30, 2009 at 00:13 UTC ( #784425=perlquestion: print w/replies, xml ) Need Help??

jimb has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to write a regex which will validate a string.

The rules:
1) string can contain any character.
2) string cannot contain a : (colon) by itself.
3) string can contain :: (two colons) by themselves.
4) string cannot contain three or more colons by themselves.

OK sip::userid@example status::code
OK ::
OK ::a::
NO :::bad_example::

I took the fist two rules and came up with ^:+. So, now the string will fail if there is any colons in it.
Rule 3 seems to be a bugger. I tried multiple variations of ::, .*, etc, but no joy.
My next steps will be passing over the string twice (once with rules 1 and 2, and once with rule 3) and if it works, I'll try rule 4.

Any help is welcomed.

P.S. I am not sure if there is a problem with moochers around here, but does asking for 'any help' mean that I want someone to write the code for me?

Replies are listed 'Best First'.
Re: Regex Validation
by GrandFather (Saint) on Jul 30, 2009 at 01:31 UTC

    The magic you need is to look around. Consider:

    use strict; use warnings; my @tests = ( '', 'sip::userid@example status::code', '::', '::a::', ':::bad_example::', ); print /^([^:]|(?<!:)::(?!:))+$/ ? "OK $_\n" : "NO $_\n" for @tests;

    BTW, the flack you got was for not (obviously) showing what you had tried. Although you did actually show [^:]+, because you didn't bother with code tags the square brackets turned the ^: into a link. There is a strong requirement here for supplicants to demonstrate that they have actually had a go at solving the problem themselves by showing the code they have tried.

    True laziness is hard work
      My thought was "the same, but backwards": since everything seems OK except a group of either one or three or more colons (delimited by non-colons), look for that pattern and reject if found.
      >perl -wMstrict -le "my $invalid = qr{ (?<! :) (?: : | :{3,}) (?! :) }xms; print '------ output ------'; for my $s (@ARGV) { print $s =~ $invalid ? 'NO' : 'OK', qq{ '$s'}; } " "" "sip::userid@example status::code" "::" "::a::" ":::bad_example::" ":" ":::" "::::" ------ output ------ NO '' OK 'sip::userid@example status::code' OK '::' OK '::a::' NO ':::bad_example::' NO ':' NO ':::' NO '::::'
Re: Regex Validation
by igelkott (Priest) on Jul 30, 2009 at 01:05 UTC

    Check out Look Ahead in the Regex tutorial. Should be enough there to get you started.

Re: Regex Validation
by ikegami (Pope) on Jul 30, 2009 at 03:22 UTC

    Readable solution, but scans entire string:

    if (grep $_!=2, map length, /(:+)/g) { die }

    Stops at first error:

    if (/: (?: :: | (?<!::)(?!:) )/x) { die }
Re: Regex Validation
by dreadpiratepeter (Priest) on Jul 30, 2009 at 00:19 UTC
    You would get better responses if you provided an example of what you tried and what didn't work. This is not a code writing site, this is a learning site.
    If you just want code written for you, I would suggest that there are many Perl programmers that you could hire to do so.

    "Worry is like a rocking chair. It gives you something to do, but it doesn't get you anywhere."
Re: Regex Validation
by Anonymous Monk on Jul 30, 2009 at 01:01 UTC
Re: Regex Validation
by ww (Archbishop) on Jul 30, 2009 at 01:32 UTC
    re your P.S.

    Not always... but when a question is asked without any code demonstrating where the poster is stuck, the question may reflect some lack of effort. That's something that violates the mores of the Monastery.

    The desiderata for postings are rather well covered in On asking for help and How do I post a question effectively?. Since you've been here since March, perhaps it's time you read those (and Markup in the Monastery as well).

Re: Regex Validation
by JavaFan (Canon) on Jul 30, 2009 at 07:49 UTC
    Without lookahead or lookbehind:
Re: Regex Validation
by pubnoop (Acolyte) on Jul 30, 2009 at 05:13 UTC

    $str =~ /^(?:[^:]|::(?!:))*\z/

    Which means $str consists only of characters other than colon ([^:]) and pairs of colons not followed by more colons (::(?!:))

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://784425]
Approved by igelkott
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (5)
As of 2021-05-07 05:16 GMT
Find Nodes?
    Voting Booth?
    Perl 7 will be out ...

    Results (87 votes). Check out past polls.