これを試して:
function get_preg_expression($mode)
{
switch ($mode)
{
case 'email':
// Regex written by James Watts and Francisco Jose Martin Moreno
// http://fightingforalostcause.net/misc/2006/compare-email-regex.php
// return '^(?:[\w!#$%&\'*+-\/=?^`{|}~]+\.)*(?:[\w!#$%&\'*+-\/=?^`{|}~]|&)+$';
return '(?:[\w!#$%&\'*+-\/=?^`{|}~]+\.)*(?:[\w!#$%&\'*+-\/=?^`{|}~]|&)+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,63})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)';
break;
}
}
先頭のブラケット式でエスケープする必要のない文字をエスケープ解除しました。それはトリックを行ったようです。より具体的には、私がエスケープした唯一の文字は'
、(a) PHP 文字列エスケープ構文によるものと、(b) PHP の preg 区切り文字として/
使用したためです。/
残念ながら、このエスケープ解除がなぜ役に立ったのかについての理論はありません。ただし、エスケープする必要があるものだけをエスケープするのがベスト プラクティスなので、「すべき」ことを考慮して解決策にたどり着いたので、安心して共有できます。答えは満足のいくものではありませんが、少なくともうまくいくようです。
テストに使用したテスト ハーネスを次に示します。これが役立つ場合に備えて、さらに一致性を追加します。
function get_preg_expression($mode)
{
switch ($mode)
{
case 'email':
// Regex written by James Watts and Francisco Jose Martin Moreno
// http://fightingforalostcause.net/misc/2006/compare-email-regex.php
// return '^(?:[\w!#$%&\'*+-\/=?^`{|}~]+\.)*(?:[\w!#$%&\'*+-\/=?^`{|}~]|&)+$';
return '(?:[\w!#$%&\'*+-\/=?^`{|}~]+\.)*(?:[\w!#$%&\'*+-\/=?^`{|}~]|&)+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,63})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)';
break;
}
}
var_dump(preg_match('/' . get_preg_expression('email') . '/', 'pwd-pr&2coop@hello.com')); // Matches
var_dump(preg_match('/' . get_preg_expression('email') . '/', 'pwd-pr&2.coop@hello.com')); // Matches
var_dump(preg_match('/' . get_preg_expression('email') . '/', 'pwd-p&r2.coop@hello.com')); // Matches
var_dump(preg_match('/' . get_preg_expression('email') . '/', 'hello')); // Does not match
var_dump(preg_match('/' . get_preg_expression('email') . '/', 'hello@world')); // Does not match
var_dump(preg_match('/' . get_preg_expression('email') . '/', 'hello@world.com')); // Matches