CodeIgniter Forums

Full Version: Why is this preg_match not working?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi guys

I have spent hours on this preg_match problem and I've Googled my ar$e off and I'm still absolutely stumped. I'm hoping someone cleverer than me (shouldn't be hard Wink ) can tell me what might be going on...

I have a form field that I'm validating with a callback. Within the callback function I'm using preg_match to make sure the field only contains alphanumeric characters, spaces, hyphens, underscores and ampersands.   My problem is with the ampersand validation:

'Foo & Bar' is valid (great!).
'Foo& Bar' is valid (great!)
'Foo&B' is valid (great!)
'Foo&Ba' is invalid (why?!)
'Foo&Bar' is invalid (why?!)

Here's my code:
PHP Code:
    public function valid_team_name($string)
    {
        if ( !
preg_match('~^[a-zA-Z0-9 _&\-]+$~'$string)) 
        
        {
            
$this->form_validation->set_message('valid_team_name''The %s field must not contain special characters');
            return 
FALSE;
        }
        else
        {
            return 
TRUE;
        }
    } 

The even stranger thing is that the preg_match pattern works when I test it with an online tester like this:
https://www.functions-online.com/preg_match.html

Any ideas would be really welcome, cheers!
Try this regex /^[~&a-z0-9 _-]+$/i

I have tested it on this site http://www.regexr.com/ and in PHP code, both working. Below is an example code.

PHP Code:
$strings = array(
 
   'Foo & Bar',
 
   'Foo& Bar',
 
   'Foo&B',
 
   'Foo&Ba',
 
   'Foo&Bar',
 
   'Foo~',
 
   'Foo & Bar ~',
 
   'Foo - Bar',
 
   'Foo_~Bar-&_~'
);

foreach (
$strings as $string)
{
 
   if preg_match('/^[~&a-z0-9 _-]+$/i'$string))
 
   {
 
       var_dump(TRUE);
 
   }
 
   else
    
{
 
       var_dump(FALSE);
 
   }


All the test strings in the array return TRUE when tested.
That's so cool of you to help, thank you!

I'm very sorry but I posted the wrong regex in my code snippet. Unfortunate side effect of trying to debug something in the middle of the night. I've fixed it now. My (not working) expression is:

~^[a-zA-Z0-9 _&\-]+$~

I want to use preg_match to allow: alphanumeric, spaces, underscores, ampersands and hyphens. I've been using the tilde as a delimiter.

How would you write that expression? In my app, it allows ampersand but rejects it if the ampersand is immediately followed by two or more characters, e.g. "Foo & Bar" is ok, "Foo&B" is ok, "Foo&Bar" is not ok.

Thanks!
To allow what you ask for (alphanumeric, spaces, underscores, ampersands and hyphens), use what I have in my first example, minus the tilde.

/^[&a-z0-9 _-]+$/i

What confuses me is that you say you use the tilde as a delimiter. A delimiter for what? And is it included in the string you are trying to validate? None of the examples you mention include a tilde character. How does the actual string look like that you are trying to validate?

The regex you say you use don't work at all for me when testing. Not even 'Foo' is valid.
This is what I meant by delimiter:
http://php.net/manual/en/regexp.referenc...miters.php
The delimiter is the first and last character in the pattern, inside the quotes. You use "/", I use "~".

Anyway... there's something weird going on because I used your pattern and my pattern in an isolated script and they both worked perfectly:

PHP Code:
$strings = array(
   'Foo & Bar',
   'Foo& Bar',
   'Foo&B',
   'Foo&Ba',
   'Foo&Bar',
   'Foo-Bar',
   'Foo_Bar',
   'Foo ~ Bar'
);

foreach (
$strings as $string)
{
if ( 
preg_match('~^[a-zA-Z0-9 _&\-]+$~'$string))
 { echo 
"$string is valid<br>"; }
 else
 { echo 
"$string is invalid<br>"; }
}; 

This script (correctly) resulted in:

Foo & Bar is valid
Foo& Bar is valid
Foo&B is valid
Foo&Ba is valid
Foo&Bar is valid
Foo-Bar is valid
Foo_Bar is valid
Foo ~ Bar is invalid

So it can't be a problem with preg_match after all.

In my app, $string is a form field that is being validated by preg_match within a callback function. My theory now is that the problem must have something to do with $string sometimes having hidden characters in, that cause the preg_match to fail. And those hidden characters are only getting added under certain circumstances involving the ampersand.

How/why is the next question!
That's what's happening!

When - and only when - the form field being validated contains, anyhwere within it, an ampersand followed immediately by two or more characters (e.g. foo&ba or foo&bar), a semi-colon is being added to the end of the field value passed to the callback function.

So, for example
- User enters "foo&b" and the callback function is passed "foo&b" to validate.
- User enters "foo&bar" and the callback function is passed "foo&bar;" to validate.

Obviously, I can workaround this now. I have no idea why it's happening though! I'm using Grocery CRUD with Codeigniter so the explanation is probably buried deep inside one of those frameworks.

Thanks for your help.