1

I have a written a piece of code which accepts an input from the user and inserts it into the Data Base. The HTML code is as follows:

<td align="center"><textarea class="txt" required=required rows="3" name="Xschool" cols="30"></textarea></td>

And I need to check the data whether is has any special symbols. I used Regular Expression for it and is as follows:

    $Xschool=$_POST['Xschool'];
    $pattern = '/[A-Z ]+$/';
$Xschool=strtoupper($Xschool);

if(!preg_match($pattern,$Xschool))
{
    echo "<pre>We are sorry. The X School ".$Xschool." is  invalid. Make sure your name contains no special symbols/numbers.</pre>";
    exit;
}

This code works correctly for many types of inputs but is not working for the input ST MARY'S. When a ' symbol is encountered the code doesn't work well. What should I do to overcome this? Please help me!! Thanks in advance.

user2644795
  • 85
  • 1
  • 1
  • 7
  • 1
    Change the pattern to: `'/[A-Z\' ]+$/'` ? :) – Nir Alfasi Aug 02 '13 at 06:43
  • 1
    Add the quote to the regex as a valid symbol... And add a starting anchor (`^`) to the regex as well. – DCoder Aug 02 '13 at 06:43
  • If `'` is valid input, why not add it to your regex?! – Sumurai8 Aug 02 '13 at 06:44
  • NO, { ' } is not a valid symbol. If I give an input as { ST MARY'S } , my code should give an error that, it doesn't accept special symbols, but I am not getting any error. So I tried to insert in DB, but there's an SQL EROR. I don't want { ' } as valid input. @Sumurai8 – user2644795 Aug 02 '13 at 06:49
  • 2
    That is **absolutely the wrong way to avoid SQL errors**. Read [this question](http://stackoverflow.com/questions/60174/how-to-prevent-sql-injection-in-php). – DCoder Aug 02 '13 at 06:53
  • @user2644795 Can you explain _why_ you don't want an apostrophe to be valid input? Is it just that you're unsure how to make it insert into the database properly? – Basic Aug 02 '13 at 12:31

7 Answers7

1

Change the pattern so that it meets your needs. For that, you first need a very clear understanding about what your needs are. '/[A-Z ]+$/' did not meet your needs; will '/[A-Z\' ]+$/' meet your needs? What about accents? What about characters outside latin-based alphabets? Answer these questions for yourself, then design a regular expression or other validation algorithm based on your answers.

Oswald
  • 31,254
  • 3
  • 43
  • 68
  • My valid input is only CAPITAL LETTERS. I should reject all those symbols/numbers other than letters. So my Regular Expression satisfies it. My problem is , it is not showing any error if I use a text as "ST MARY'S ". I should get an error for this. @oswald – user2644795 Aug 02 '13 at 06:53
  • If your valid input is only CAPITAL LETTERS, then why is there a space in the `[A-Z ]` group? If you want only capital letters from the latin alphabet, use `/^[A-Z]*$/`. Please consider what I said about a *very clear understanding about what your needs are*. – Oswald Aug 02 '13 at 06:57
  • I am sorry. Now I'll explain you. My code should accept an input from the user which could be only letters and can use spaces. I am going to convert the data into uppercase and match with the regex '/[A-Z ]+$/'. When I give an input like "Sravan" it is accepting(this is what I want), "St Mary'" it is showing an error (this is too what I want), but when I give input as "St Mary's " it should throw an error but it isn't. – user2644795 Aug 02 '13 at 07:06
  • That's because the `S` after the `'` matches your regular expression. The `^` in my regular expression from 25 minutes ago prevents that by matching the start of the string. To also allow spaces, use `/^[A-Z ]*$/`. BTW, what do you call the thing that Şebnem Ferah has at the start of her first name? Is that a capital letter, too? If it is, that make things a lot more complicated. – Oswald Aug 02 '13 at 07:22
  • Yes now I got it. Thanks for the answer and I'll change my code @oswald – user2644795 Aug 02 '13 at 07:28
1

There's something wrong with your basic understanding.

/[A-Z ]+$/

will match any string that contains a line ending in A-Z or space.

I suggest that you want:

if(preg_match('/[^A-Z ]/', $Xschool))
{
 ...
}

Which will match any string containing a char that is not A-Z or space.

pguardiario
  • 53,827
  • 19
  • 119
  • 159
  • 1
    This is the right answer to the specific question but is NOT the right way to avoid SQL injection attacks - and `St Mary's` seems like it _should_ be a valid school name but you're rejecting it as your system can't handle it. Learn about parameterised queries and avoid this issue altogether – Basic Aug 02 '13 at 07:19
  • 1
    Uh, yeah. Nobody said anything about SQL injection attacks, although obviously this method would be outstanding in that capacity. – pguardiario Aug 02 '13 at 12:02
0

Simply include the ' in the match:

    $Xschool=$_POST['Xschool'];
    $pattern = "/[A-Z ']+$/";
$Xschool=strtoupper($Xschool);

if(!preg_match($pattern,$Xschool))
{
    echo "<pre>We are sorry. The X School ".$Xschool." is  invalid. Make sure your name contains no special symbols/numbers.</pre>";
    exit;
}
Ivan Buttinoni
  • 4,110
  • 1
  • 24
  • 44
  • NO, { ' } is not a valid symbol. If I give an input as { ST MARY'S } , my code should give an error that, it doesn't accept special symbols, but I am not getting any error. So I tried to insert in DB, but there's an SQL EROR. I don't want { ' } as valid input. @ivan – user2644795 Aug 02 '13 at 06:50
0

Try this Regular expressions.

[a-zA-Z0-9\'\s]{0,50}

this will allow small & capital character and 0 to 9 digit up to 50 name in length.

If you want to use only capital word then.

[A-Z\'\s]{0,50}
stema
  • 90,351
  • 20
  • 107
  • 135
Manthan Patel
  • 429
  • 1
  • 4
  • 6
0

Try this

 $Xschool=$_POST['Xschool'];
$pattern = '/^[a-zA-Z][a-zA-Z ]*$/';
$Xschool=strtoupper($Xschool);

if(!preg_match($pattern,$Xschool))
{
    echo "<pre>We are sorry. The X School ".$Xschool." is  invalid. Make sure your name contains no special symbols/numbers.</pre>";
    exit;
}
Dev
  • 612
  • 2
  • 13
  • 33
0

Your pattern, /[A-Z ]+$/, does not include a starting anchor. That means when you try to match it against ST MARY'S, it matches the ending S and your code doesn't see any errors. Changing the pattern to /^[A-Z ]+$/ will fix that problem.

However, based on your comments you have a much bigger problem - you are blindly passing user input to the SQL query without sanitizing it, which means you are vulnerable to SQL injection attacks. Learn the right way to defend against these attacks instead of coming up with misguided bandaids like this regex.

Community
  • 1
  • 1
DCoder
  • 12,962
  • 4
  • 40
  • 62
0

Another approach:

Replace all VALID characters, in your scenario the A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,SPACE and any other VALID character with nothing "". Then, if the remaining string has length > 0 that means some other INVALID character must exist.

<?php

    function isStringOnlyAZSPACE($the_string)
    {
        $valid_chars = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',' ');

        $the_string  = str_replace($valid_chars, "", $the_string);

        return (strlen($the_string)==0);
    }

    echo isStringOnlyAZSPACE("ST MARY'S")?"true":"false"; // FALSE

    echo isStringOnlyAZSPACE("ST MARYS")?"true":"false"; // TRUE

?>

see it in action here http://3v4l.org/GvVi6

i must also repeat the comment from @DCoder in your question "That is absolutely the wrong way to avoid SQL errors."

Sharky
  • 6,154
  • 3
  • 39
  • 72