• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 371
  • Last Modified:

Regular expression needed

I have a form field. In this field you may no enter something that will result in a search for the letters FG on their own
Anything letter or digit in front or any letter or digit after FG is fine

Valid queries:

AFG
AFG01
FGA
FGA01
FG1
FG1 OR FG2

The current regexp is this:

^FG$|[ ]FG$|[ ]FG[ ]

However in this I am able to search using
(AB OR FG)
and also ((((FG XXX)))
which I need to be not allowed.

Thanks

Michel
0
Michel Plungjan
Asked:
Michel Plungjan
  • 7
  • 4
  • 3
  • +3
1 Solution
 
stefan73Commented:
Hi mplungjan,
What about
^\w*FG\w*$

(Assuming you want any number of letter/digit before FG)

Enjoy,

Stefan
0
 
Michel PlungjanIT ExpertAuthor Commented:
Here is my test script.

Seems your regexp is not complete
<script>
reg = /^\w*FG\w*$/
function testReg(str,valid) {
  v = (valid)?"Valid:":"Not Valid"
  test = reg.test(str);
  p = ((test && valid) || (!test && !valid))?"passed":"not passed"
  txt = "<hr>"+v+" |"+str+"| "+p+ " ("+test+")"
  document.write(txt)
}

testReg('FG',0)
testReg(' FG',0)
testReg('(AB OR FG)',0)
testReg('(AB OR FG0)',1)
testReg('FG0',1)
testReg('AFGB',1)
testReg(' FG0',1)

</script>

I get

Not Valid |FG| not passed (true) <<<<<<<
Not Valid | FG| passed (false)
Not Valid |(AB OR FG)| passed (false)
Valid: |(AB OR FG0)| not passed (false) <<<<<<<
Valid: |FG0| passed (true)
Valid: |AFGB| passed (true)
Valid: | FG0| not passed (false) <<<<<<<<
0
 
NorCal2612Commented:
Would this work?

#!/usr/bin/perl

$in = shift;

if ($in =~ /(\d|\w)FG(\d|\w)/ig) { print "OK\n"; } else { print "Not OK\n"; }

# end script

Good luck! :D
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

 
Michel PlungjanIT ExpertAuthor Commented:
Please plug it into my test page and see it does not work:

Not Valid |FG| passed (false)
--------------------------------------------------------------------------------
Not Valid | FG| passed (false)
--------------------------------------------------------------------------------
Not Valid |(AB OR FG)| passed (false)
--------------------------------------------------------------------------------
Valid: |(AB OR FG0)| not passed (false) <<<<
--------------------------------------------------------------------------------
Valid: |FG0| not passed (false) <<<<<<<<<
--------------------------------------------------------------------------------
Valid: |AFGB| passed (true)
--------------------------------------------------------------------------------
Valid: | FG0| not passed (false)  <<<<<<<
0
 
NorCal2612Commented:
Ok sorry I misread your initial requirements slightly. This worked for me in all cases:

#!/usr/bin/perl

$in = shift;

if ($in =~ /(\d|\w)FG/ig || $in =~ /FG(\d|\w)/ig) { print "OK\n"; } else { print "Not OK\n"; }
0
 
stefan73Commented:
mplungjan,

I'm not quite sure for which cases you need a match and which must explicitly fail... ...,0 must succeed, ,1 must fail?

> testReg('FG',0)
> testReg(' FG',0)
> testReg('(AB OR FG)',0)
> testReg('(AB OR FG0)',1)
> testReg('FG0',1)
> testReg('AFGB',1)
> testReg(' FG0',1)



Stefan
0
 
Michel PlungjanIT ExpertAuthor Commented:
Here is a version with my latest suggestion - please note it is a NEGATIVE test - my test does not pass all examples

<script>
//reg = /^\w*FG\w*$/; // positive test
//reg = /(\d|\w)FG(\d|\w)/ig; // positive test
reg = /^FG$|[ ]FG[ ]|FG[^a-z0-9]/; // negative test

function testReg(str,valid) {
  v = (valid)?"Valid:":"Not Valid"
  test = reg.test(str);
//  p = ((test && valid) || (!test && !valid))?"passed":"not passed"; // positive test
  p = ((test && !valid) || (!test && valid))?"passed":"not passed"; // negative test
  txt = "<hr>"+v+" |"+str+"| "+p+ " ("+test+")"
  document.write(txt)
}

testReg('FG',0); // not valid
testReg(' FG',0); // not valid
testReg(' FG ',0); // not valid
testReg('(AB OR FG)',0); // not valid
testReg('(AB OR FG0)',1); // valid
testReg('FG0',1); // valid
testReg('AFGB',1); // valid
testReg(' FG0',1); // valid

</script>
0
 
Michel PlungjanIT ExpertAuthor Commented:
ALmost

<script>
//reg = /^\w*FG\w*$/; // positive test
//reg = /(\d|\w)FG(\d|\w)/ig; // positive test
reg = /^FG$|[ ]FG[ ]|^FG[ ]|^[ ]FG$|FG[^a-z0-9]/; // negative test

function testReg(str,valid) {
  v = (valid)?"Valid:":"Not Valid"
  test = reg.test(str);
//  p = ((test && valid) || (!test && !valid))?"passed":"not passed"; // positive test
  p = ((test && !valid) || (!test && valid))?"passed":"not passed"; // negative test
  txt = "<hr>"+v+" |"+str+"| "+p+ " ("+test+")"
  document.write(txt)
}

testReg('FG',0)
testReg(' FG',0)
testReg(' FG ',0)
testReg('(AB OR FG)',0)
testReg('(AB OR FG0)',1)
testReg('FG0',1)
testReg('AFGB',1); <<<<<<< does not pass !!!
testReg(' FG0',1)

</script>
0
 
Adam314Commented:
This doesn't look quite like perl code....  So i tested it using perl, and every one passed:

#NOTE: If it matches this pattern, it is NOT valid
if(  /\bFG\b/  ){
    print "NOT VALID";
}
else {
    print "Valid";
}


Here is the perl code:
#!/usr/bin/perl
use strict;

sub testReg {
      my ($str, $valid) = @_;
      my $v = ($valid)?"    Valid":"Not Valid";
      my $test = ($str =~ /\bFG\b/);
      my $p = ((!$test && $valid) || ($test && !$valid))?"    passed":"not passed";
      print "$v: $p: $str\n";
}

testReg('FG',0);
testReg(' FG',0);
testReg(' FG ',0);
testReg('(AB OR FG)',0);
testReg('(AB OR FG0)',1);
testReg('FG0',1);
testReg('AFGB',1);
testReg(' FG0',1);
0
 
mjcoyneCommented:
Try it this way:

#!/usr/bin/perl -w
use strict;

while (<DATA>) {
    if (/^FG$|(?<=[\s"'(])FG(?=[\s'")])/) {
        chomp;
        print "$_ not allowed\n";
    }
}
__DATA__
FG
AFG
AFG01
FGA
FGA01
FG1
FG1 OR FG2
(FG OR AB)
(AB OR FG)
(AB OR FG0)
"FG"
(FG)
'FG'

The output is:

FG not allowed
(FG OR AB) not allowed
(AB OR FG) not allowed
"FG" not allowed
(FG) not allowed
'FG' not allowed

all other lines are allowed.  I assumed you would like to disallow 'FG' and "FG", if this is an incorrect assumption, you can remove the ' and the " from the character classes used by the lookbehid and lookahead assertions.

Will this do what you need?
0
 
mjcoyneCommented:
Actually, you could tighten that up a bit further by using:

#!/usr/bin/perl -w
use strict;

while (<DATA>) {
    if (/^\s*FG\s*$|(?<=[\s"'(])FG(?=[\s'")])/) {
        chomp;
        print "$_ not allowed\n";
    }
}
__DATA__
FG
AFG
AFG01
FGA
FGA01
FG1
FG1 OR FG2
(FG OR AB)
(AB OR FG)
(AB OR FG0)
"FG"
(FG)
'FG'
 FG
FG
 FG
'FG)

instead.  Changing it to ^\s*FG\s*$ will disallow FG preceded or followed by nothing but spaces (either <space>FG, FG<space>, and <space>FG<space>, if on a line by themselves, will also be disallowed).
0
 
ozoCommented:
while( <DATA> ){
    if( /(?<!\w)FG(?!\w)/ ){
        chomp;
        print "$_ not allowed\n";
    }
}
__DATA__
AFG
AFG01
FGA
FGA01
FG1
FG1 OR FG2
(FG OR AB)
(AB OR FG)
(AB OR FG0)
"FG"
(FG)
'FG'
 FG
FG
 FG
'FG)
0
 
ozoCommented:
/^\s*FG\s*$|(?<=[\s"'(])FG(?=[\s'")])/
fails on
FG A
0
 
Michel PlungjanIT ExpertAuthor Commented:
It is not perl because I did not ask for perl. Just a regexp. So please no perl or chomp
I am not using perl but a java parser - the regex experts sit here and most regexps out there are perl 5 compliant.

thanks for any help

Michel
0
 
ozoCommented:
/(?<!\w)FG(?!\w)/
0
 
Adam314Commented:
I figured that was the reason... and gave a regex that worked on the examples provided.

have you tried   /\bFG\b/    (if the string matches, it is NOT valid)
0
 
mjcoyneCommented:
Chomp is not necessary for the regular expression I provided, it's just in a script that tests the regex, which is (/^\s*FG\s*$|(?<=[\s"'(])FG(?=[\s'")])/).

Does (/^\s*FG\s*$|(?<=[\s"'(])FG(?=[\s'")])/) work for you?
0
 
mjcoyneCommented:
oops -- remove the parentheses left over from the "if" statement...

Does /^\s*FG\s*$|(?<=[\s"'(])FG(?=[\s'")])/ work for you?
0
 
Michel PlungjanIT ExpertAuthor Commented:
Seems Adam has the lead so far.
http://www.experts-exchange.com/Programming/Programming_Languages/Perl/Q_21901845.html#17001773

seems to work perfectly. I will run it through some more tests but that is very promising
0
 
Michel PlungjanIT ExpertAuthor Commented:
Thanks all.

Very simple and effective solution

Michel
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

  • 7
  • 4
  • 3
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now