2

Possible Duplicate:
What do ^ and $ mean in a regular expression?

I'm not good at all at regular expression, i know they are so much important but never found the time to study them. Anyway i'm just tring to ensure that, among these strings:

MAX_AGE_60
MAX_AGE_80
...
MAX_AGE_X

where more in general X is a integer, at least one match is found and get the number X. So following the example on PHP documentation i wrote this:

// Starts and ends with the literal 'MAX_AGE_' followed by a group that is a 
// number with at least one digit. Case insensitive
$pattern = '/^MAX_AGE_(?P<max>\d+)$/i';

$test    = 'MAX_AGE_80';
$matches = array();

preg_match($pattern, $test, $matches);
var_dump($matches);

The result is wrong (suprise...):

array (size=0)
  empty

Removing start/end delimiters (^ and $) i get the correct result:

array (size=3)
  0     => string 'MAX_AGE_80' (length=10)
  'max' => string '80' (length=2)
  1     => string '80' (length=2)

So why i can't force that the string must start and end with that pattern? And how should interpret the result array? I mean indexes 0, 1 and max?

Community
  • 1
  • 1
  • In your specific case `^` and `$` could stay in the regex, if you also used the `/m` modifier to make both multi-line aware. – mario May 18 '12 at 15:29
  • 1
    I get the expected result with/without `^` and `$`. Where is the problem? – Salman A May 18 '12 at 15:40
  • @SalmanA does not work with the first (using `^` and `$`), removing them it works. Why? –  May 18 '12 at 15:47
  • ^ and $ are telling the regex that ^ is the line start and $ is the line end. If you want to use word boundaries use \b(regex)\b instead. – Taha Paksu May 18 '12 at 15:49
  • You example code seems to work as-is: http://ideone.com/ttA8X – Salman A May 18 '12 at 15:49
  • You're making us guess your actual input string. Unclear if it's in fact a multi-line input text, or if there are just trailing newlines. Anyway, that's your answer. – mario May 18 '12 at 15:49
  • 1
    umm...I don't see this as dublicate... 1. the question is not, what `^`and `$`'s function is, but why they don't work as intended. 2. the question about the output of the named subpattern has not been answered (short answer: index 0 is the whole matched string, all other numeric indices are matches to subpatterns, additional preg_match gives you the matches to named pattern with the name as index) – cypherabe May 18 '12 at 16:08

2 Answers2

2

I'm not sure what you're doing between the parentheses there. Try this:

$pattern = '/^MAX_AGE_[\p{N}]+$/iu';

And the difference between ^$ and not, is that they flag only matches that are at the beginning and/or the end of the LINE

You can use this site to test your expressions (non unicode): http://www.gskinner.com/RegExr/

Neil Aitken
  • 7,856
  • 3
  • 41
  • 40
Leandro Zhuzhi
  • 304
  • 1
  • 7
  • 17
  • Sorry i had not read your question well. Try this: `$pattern = '/MAX_AGE_([\p{N}]+)?/ium';` and use `preg_match_all` (it returns an array, look this up in php documentation online) – Leandro Zhuzhi May 18 '12 at 15:39
  • I'm sure that my test string will always contain at maximum 1 match, so why should i use preg_match_all? –  May 18 '12 at 15:48
  • 1
    Oh, sorry that wasn't very clear. If you are certain there will be only 1 match then you dont need to use preg_match_all. I thought you wanted to capture at least 1 match. About your question, your string is not only one line. Regexp engine will search the entire block of text u give it, and so the pattern (designed for a line) will not match against several lines. – Leandro Zhuzhi May 18 '12 at 15:52
0

try using

$pattern = '/^MAX_AGE_(?P<max>\d+)\s*$/i';

as there might be whitespace before the line ends.

Taha Paksu
  • 15,371
  • 2
  • 44
  • 78