1

I need to write a regex in PHP, the condition is A-Z, a-z, 0-9, :, -, _, but in the end of string cannot be :

This is what I tried

<?php

$strings = [
    'aaa:bbb-cool',
    'aaa:bbb-cool-',
    'aaa-22-bbb_cool3',
    'aaa:bbb-cool:',
    'aaa_bbb-cool:',
    'aaa_bbb-cool',
    'bbbb:>dd',
    'hihi%',
    '大家好',
    '0000000000',
    '11111:2222:3333',
    '11111:2222:3333:',
    'DDD@@@1',
    '大家好',
];

$pattern = '/[0-9a-zA-Z]+$/i';

foreach ($strings as $key => $string) {
    var_dump('number '.$key .' '. $string.' is '.preg_match($pattern, $string));
}

and the result is

string(26) "number 0 aaa:bbb-cool is 1"
string(27) "number 1 aaa:bbb-cool- is 0"
string(30) "number 2 aaa-22-bbb_cool3 is 1"
string(27) "number 3 aaa:bbb-cool: is 0"
string(27) "number 4 aaa_bbb-cool: is 0"
string(26) "number 5 aaa_bbb-cool is 1"
string(22) "number 6 bbbb:>dd is 1"
string(19) "number 7 hihi% is 0"
string(23) "number 8 大家好 is 0"
string(24) "number 9 0000000000 is 1"
string(30) "number 10 11111:2222:3333 is 1"
string(31) "number 11 11111:2222:3333: is 0"
string(22) "number 12 DDD@@@1 is 1"
string(24) "number 13 大家好 is 0"
  1. I know I do not really prevent ":" in the end, cause number 1 should be true, how to make it right
  2. why is number 6 and number 12 be true?
Chan
  • 1,707
  • 5
  • 20
  • 36

1 Answers1

3

You are not preventing, nor matching the : with your pattern. To match :, the consuming part should contain : char. Strings 6 and 12 match because your '/[0-9a-zA-Z]+$/i' pattern just matches any ASCII digit or letter, 1 or more times, at the end of the string and does not check anything before them.

You may fix the expression using

'~^[\w:-]+$(?<!:)~'

See the regex demo.

It matches:

  • ^ - start of string
  • [\w:-]+ - 1 or more word chars (here, ASCII letters, digits or _), : or - chars
  • $ - end of string (you may also use \z to match the very end of the string, or just add D after the regex delimiter ~)
  • (?<!:) - a negative lookbehind that fails the match if there is a : char right at the end of the string.
Wiktor Stribiżew
  • 561,645
  • 34
  • 376
  • 476