php preg_grep и умлаут / акцент

У меня есть массив, состоящий из терминов, некоторые из которых содержат акцентированные символы. Я делаю preg grep, как это

$data= array('Napoléon','Café'); $result = preg_grep('~' . $input . '~i', $data); 

Поэтому, если пользователь вводит «le», я также хочу, чтобы результат «Napoléon» соответствовал, что не работает с командой ablove.

Я сделал некоторые поиски и обнаружил, что эта функция может быть актуальной

 preg_match("/[\w\pL]/u",$var); 

Как я могу объединить их и заставить работать?

Это невозможно с помощью шаблона регулярного выражения. Это не потому, что вы не можете сказать, что двигатель регулярного выражения соответствует всем «e» и подобным. Тем не менее, можно сначала нормализовать входные данные (как массив, так и вход поиска), а затем выполнить поиск нормализованных данных, но вернуть результаты для ненормированных данных.

В следующем примере я использую транслитерацию для выполнения такой нормализации, я думаю, это то, что вы ищете:

 $data = ['Napoléon', 'Café']; $result = array_translit_search('le', $data); print_r($result); $result = array_translit_search('leó', $data); print_r($result); 

Примерный результат:

 Array ( [0] => Napoléon ) Array ( [0] => Napoléon ) 

Сама функция поиска довольно прямолинейна, как указано выше, транслитерируя входные данные, делая preg_grep и затем возвращая исходные совпадения:

 /** * @param string $search * @param array $data * @return array */ function array_translit_search($search, array $data) { $transliterator = Transliterator::create('ASCII-Latin', Transliterator::REVERSE); $normalize = function ($string) use ($transliterator) { return $transliterator->transliterate($string); }; $dataTrans = array_map($normalize, $data); $searchTrans = $normalize($search); $pattern = sprintf('/%s/i', preg_quote($searchTrans)); $result = preg_grep($pattern, $dataTrans); return array_intersect_key($data, $result); } 

Для этого кода требуется Transliterator из внутреннего расширения , его можно заменить любой другой аналогичной транслитерацией или функцией перевода.

Я не могу предложить использовать str_replace здесь str_replace ., Если вам нужно вернуться к таблице переводов, вместо этого используйте strtr . Это то, что вы ищете. Но я предпочитаю библиотеку, которая приносит перевод с ее собственным, особенно если это Intl lib, вы обычно не можете его победить.

Вы можете написать примерно так:

 $data = array('Napoléon','Café'); // do something with your input, but for testing purposes it will be simply as you wrote in your example $input = 'le'; foreach($data as $var) { if (preg_match("/".str_replace(array("é"....), array("e"....), $input)."/i", str_replace(array("é"....), array("e"....), $var))) //do something as there is a match } 

На самом деле вам даже не нужно регулярное выражение в этом случае, простых strpos будет достаточно.