To me they look the same... why are they different in practice?
echo preg_match("/^a|b|c$/", "aaaa");
echos 1
and echo preg_match( "/^a$|^b$|^c$/", "aaaa");
echos 0
/^a|b|c$/
matches all values starting with "a", containing "b" or ending with "c".
/^a$|^b$|^c$/
matches just "a" or "b" or "c" and no other values.
echo preg_match("/^a|b|c$/", "aaaa"); // 1
echo preg_match("/^a|b|c$/", "zbaa"); // 1
echo preg_match("/^a|b|c$/", "aaac"); // 1
echo preg_match("/^a$|^b$|^c$/", "aaaa"); // 0
echo preg_match("/^a$|^b$|^c$/", "zbaa"); // 0
echo preg_match("/^a$|^b$|^c$/", "aaac"); // 0
echo preg_match("/^a$|^b$|^c$/", "a"); // 1
echo preg_match("/^a$|^b$|^c$/", "b"); // 1
echo preg_match("/^a$|^b$|^c$/", "c"); // 1
echo preg_match("/^a$|^b$|^c$/", "d"); // 0
In order for the first one to be exactly the same as the second one you must use a group:
echo preg_match("/^(a|b|c)$/", "aaaa");
Otherwise it means it has to match ^a
or b
or c$