У меня есть массив, состоящий из терминов, некоторые из которых содержат акцентированные символы. Я делаю 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
будет достаточно.