PHP 使用 preg_match 将数组中的项目与可以包含或不包含重音字符的值匹配
PHP using preg_match to match items in array with values that can or not contain accent characters
preg_match
必须将 $string
变量中的任何单词(只要它们至少有 3 个字符长)与 $forbidden
数组中的任何单词相匹配,但问题是:
如果 $string
包含单词 mamiferos(带有重音符号)而不是 mamiferos,它也应该是一场比赛。如果 acompanar 在禁止数组列表中,但用户决定键入 acompanar(不带重音符号),则同样适用。
$forbidden = array('mamiferos', 'acompañar');
$string = 'los mamíferos corren libres y quieren acompanar a su madre';
if(preg_match('/\b(?:'.implode('|', $forbidden).'){3,}/i', $string)) {
echo 'match!';
} else {
echo 'nope...';
}
这对我有用,您要做的就是从输入字符串中删除重音字符,尽管这不是最佳答案。
$forbidden = array('mamiferos', 'acompañar');
$string = 'los mamíferos corren libres y quieren acompanar a su madre';
$stripted_accent = remove_accent($string);
if(preg_match('/(' . remove_accent(implode('|', $forbidden)) .')/', $stripted_accent)) {
echo 'match!';
} else {
echo 'nope...';
}
function remove_accent($accent) {
return strtr(utf8_decode($accent), utf8_decode('àáâãäçèéêëìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ'), 'aaaaaceeeeiiiinooooouuuuyyAAAAACEEEEIIIINOOOOOUUUUY');
}
我建议一种解决方案,该解决方案基于从过滤字符串和禁用词中删除任何组合 Unicode 字符。它将需要 intl
扩展名 (sudo apt install php7.4-intl && sudo phpenmod intl
)。首先,它将 Uncode 字符串分解为字符和组合字母修饰符,其次,它删除所有修饰符 (\p{M}
):
<?php
$string = 'los mamíferos corren libres y quieren acompanar a su madre';
$forbidden = ['mamiferos', 'acompañar'];
function strip (string $accented): string {
$decomposed = Normalizer::normalize ($accented, Normalizer::FORM_D);
return preg_replace ('/\p{M}/u', '', $decomposed);
}
function filter (string $string, array $words): bool {
$regex = '/\b(?:' . implode ('|', $words) . ')/i';
return preg_match (strip ($regex), strip ($string));
}
echo ((filter ($string, $forbidden) ? 'match!' : 'nope...') . "\n");
顺便说一句,我不明白你的正则表达式中 {3,}
的含义,我把它从我的正则表达式中删除了。如果您认为它会匹配一个包含三个或更多禁止词的字符串,那您就错了:禁止词只有在紧接在一起时才会匹配。
preg_match
必须将 $string
变量中的任何单词(只要它们至少有 3 个字符长)与 $forbidden
数组中的任何单词相匹配,但问题是:
如果 $string
包含单词 mamiferos(带有重音符号)而不是 mamiferos,它也应该是一场比赛。如果 acompanar 在禁止数组列表中,但用户决定键入 acompanar(不带重音符号),则同样适用。
$forbidden = array('mamiferos', 'acompañar');
$string = 'los mamíferos corren libres y quieren acompanar a su madre';
if(preg_match('/\b(?:'.implode('|', $forbidden).'){3,}/i', $string)) {
echo 'match!';
} else {
echo 'nope...';
}
这对我有用,您要做的就是从输入字符串中删除重音字符,尽管这不是最佳答案。
$forbidden = array('mamiferos', 'acompañar');
$string = 'los mamíferos corren libres y quieren acompanar a su madre';
$stripted_accent = remove_accent($string);
if(preg_match('/(' . remove_accent(implode('|', $forbidden)) .')/', $stripted_accent)) {
echo 'match!';
} else {
echo 'nope...';
}
function remove_accent($accent) {
return strtr(utf8_decode($accent), utf8_decode('àáâãäçèéêëìíîïñòóôõöùúûüýÿÀÁÂÃÄÇÈÉÊËÌÍÎÏÑÒÓÔÕÖÙÚÛÜÝ'), 'aaaaaceeeeiiiinooooouuuuyyAAAAACEEEEIIIINOOOOOUUUUY');
}
我建议一种解决方案,该解决方案基于从过滤字符串和禁用词中删除任何组合 Unicode 字符。它将需要 intl
扩展名 (sudo apt install php7.4-intl && sudo phpenmod intl
)。首先,它将 Uncode 字符串分解为字符和组合字母修饰符,其次,它删除所有修饰符 (\p{M}
):
<?php
$string = 'los mamíferos corren libres y quieren acompanar a su madre';
$forbidden = ['mamiferos', 'acompañar'];
function strip (string $accented): string {
$decomposed = Normalizer::normalize ($accented, Normalizer::FORM_D);
return preg_replace ('/\p{M}/u', '', $decomposed);
}
function filter (string $string, array $words): bool {
$regex = '/\b(?:' . implode ('|', $words) . ')/i';
return preg_match (strip ($regex), strip ($string));
}
echo ((filter ($string, $forbidden) ? 'match!' : 'nope...') . "\n");
顺便说一句,我不明白你的正则表达式中 {3,}
的含义,我把它从我的正则表达式中删除了。如果您认为它会匹配一个包含三个或更多禁止词的字符串,那您就错了:禁止词只有在紧接在一起时才会匹配。