php preg_grep和umlaut/accent

php preg_grep和umlaut/accent,php,regex,character-encoding,transliteration,Php,Regex,Character Encoding,Transliteration,我有一个由术语组成的数组,其中一些包含重音字符。我做了这样的预格雷普 $data= array('Napoléon','Café'); $result = preg_grep('~' . $input . '~i', $data); 因此,如果用户输入'le',我还希望结果'Napoléon'匹配,这不适用于ablove命令 我做了一些搜索,发现这个函数可能是相关的 preg_match("/[\w\pL]/u",$var); 我如何将这些结合起来并使其工作?您可以这样写: $data =

我有一个由术语组成的数组,其中一些包含重音字符。我做了这样的预格雷普

$data= array('Napoléon','Café');
$result = preg_grep('~' . $input . '~i', $data);
因此,如果用户输入'le',我还希望结果'Napoléon'匹配,这不适用于ablove命令

我做了一些搜索,发现这个函数可能是相关的

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

我如何将这些结合起来并使其工作?

您可以这样写:

$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就足够了。

仅使用正则表达式模式是不可能的。这并不是因为您不能告诉正则表达式引擎匹配所有的“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\u 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);
}
此代码需要,您可以用任何其他类似的音译或翻译函数替换它


顺便说一句,我不建议在这里使用
str\u replace
,如果您需要返回到翻译表,请使用。这就是你要找的。但是我更喜欢一个自带翻译的库,特别是如果是Intl库,你通常无法打败它。

什么是
var\u dump($input)给予?您没有在问题中提供这一点。$input实际上是用户输入的内容,在上面的例子中是“le”。但这是两个不同的字符串。
le
应该如何匹配
,这是不同的。这应该遵循哪条规则?你猜这两件事可能会起作用,我认为你根本无法将它们结合起来。是什么让你认为这样的组合是可能的?请同时提供
\pL
preg.*
函数的参考,您在这里指的是什么?您可以在twitter引导typeahead(自动完成)中找到类似的函数。其基本思想是,即使用户类型“cafe”、“Café”也应作为建议返回。您可以首先在用户输入和数据(在时间变量中)中替换所有字符,如é(它们不可能很多),然后您的正则表达式将完全工作。非常感谢。这确实是一个可行的解决办法。我仍然在看是否有办法在一个正则表达式行中完成它。@user1906418如果你要使用此解决方案,最好在
$input
中组合替换字符,并继续使用
preg_grep()
不要使用
str_replace
来完成此工作,如果你真的需要,请使用。非常感谢你的详细回答!对于strtr vs str_replace问题,它们执行的不是相同的操作吗?是因为性能还是其他原因,strtr更好?是因为这些函数做了一些不同的事情。您需要的是翻译,而不是替换,在替换的字符串中替换,然后在已经替换了两次的字符串中再次替换。你只需要翻译,而不是那些倍数。就性能而言,我不知道。也许strtr也更快,但谁在乎呢?