我有一个由术语组成的数组,其中一些包含重音字符。我像这样做一个preg grep
$data= array('Napoléon','Café');
$result = preg_grep('~' . $input . '~i', $data);
因此,如果用户输入'le',我也希望匹配结果'Napoléon',这与ablove命令无关。
我做了一些搜索,发现这个功能可能是相关的
preg_match("/[\w\pL]/u",$var);
如何将这些结合起来并使其有效?
答案 0 :(得分:2)
仅使用正则表达式模式无法实现。这不是因为你不能告诉正则表达式引擎匹配所有“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
from the Intl extension,您可以将其替换为任何其他类似的音译或翻译功能。
我建议不要在这里使用str_replace
btw。如果您需要回退到翻译表,请改用strtr
。这就是你要找的东西。但我更喜欢一个带有翻译功能的库,特别是如果它是Intl lib,你通常无法击败它。
答案 1 :(得分:1)
你可以这样写:
$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
就足够了。