我的数据库里有阿拉伯文,上面写着对话/塔什基尔。要搜索没有diacritics/tashkeel的用户类型,我和我可以使用全文搜索语句成功搜索,但不能使用正则表达式突出显示搜索词:
$str="اِنَّ الَّذِیۡنَ اٰمَنُوۡا وَ عَمِلُوا الصّٰلِحٰتِ وَ اَخۡبَتُوۡۤا اِلٰی رَبِّہِمۡ ۙ اُولٰٓئِکَ اَصۡحٰبُ الۡجَنَّۃِ ۚ ہُمۡ فِیۡہَا خٰلِدُوۡنَ";
$ptr="عملوا";
$result = preg_replace("/$ptr/", '<span style="background:yellow">' . $ptr . '</span>', $str);
echo $result;对如何解决这个问题有什么想法吗?
发布于 2021-05-10 22:12:43
您的字符串具有额外的字符,如tashkil。但是您想要匹配的字符没有tashkil,所以解决方案是替换额外的字符,并使两个字符串相似。
<?php
function stripDiacritics($str) {
$diacritic = array("ِ" ,"ٰ" ,"ّ" ,"ۡ" ,"ٖ" ,"ٗ" ,"ؘ" ,"ؙ" ,"ؚ" ,"ٍ" ,"َ" ,"ُ", "ٓ" ,"ْ" , "ٌ" , "ٍ", "ً", "ّ", "ۤ");
$str = str_replace($diacritic, '', $str);
return $str;
}
$str="اِنَّ الَّذِیۡنَ اٰمَنُوۡا وَ عَمِلُوا الصّٰلِحٰتِ وَ اَخۡبَتُوۡۤا اِلٰی رَبِّہِمۡ ۙ اُولٰٓئِکَ اَصۡحٰبُ الۡجَنَّۃِ ۚ ہُمۡ فِیۡہَا خٰلِدُوۡنَ";
$words = explode(" ",$str);
$resultText='';
foreach ($words as $word) {
$strippedWord = stripDiacritics($word);
$ptr="عملوا";
if ($strippedWord == $ptr) {
$resultText .= ' <span style="background:yellow">'.$word.'</span>';
}
else {
$resultText .= ' '.$word;
}
}
echo $resultText;

发布于 2021-05-10 23:58:32
虽然@Artier的答案可能是可以接受的,但在源代码中使用松散的UTF-8组合标记并不是最好的主意,而且,从我从Google收集到的信息来看,它们可能没有涵盖所有阿拉伯语的数字符号/组合标记。
免责声明:我对阿拉伯语知之甚少,但我对UTF-8很挑剔.
@Artier的答案似乎是从this question上接受的答案中筛选出来的,但接受的答案往往不是最佳的解决方案。来自同一组答案的另外两个选项之一很可能更接近规范正确。
function strip_arabic_diacritics_1($str) {
return preg_replace("~[\x{064B}-\x{065B}]~u", "", $str);
}
function strip_arabic_diacritics_2($str) {
$ranges = [
"~[\x{0600}-\x{061F}]~u",
"~[\x{063B}-\x{063F}]~u",
"~[\x{064B}-\x{065E}]~u",
"~[\x{066A}-\x{06FF}]~u",
];
return preg_replace($ranges, "", $str);
}
$str="اِنَّ الَّذِیۡنَ اٰمَنُوۡا وَ عَمِلُوا الصّٰلِحٰتِ وَ اَخۡبَتُوۡۤا اِلٰی رَبِّہِمۡ ۙ اُولٰٓئِکَ اَصۡحٰبُ الۡجَنَّۃِ ۚ ہُمۡ فِیۡہَا خٰلِدُوۡنَ";
$ptr="عملوا";
var_dump(
$str,
strip_arabic_diacritics_1($str),
strip_arabic_diacritics_2($str)
);输出:
string(265) "اِنَّ الَّذِیۡنَ اٰمَنُوۡا وَ عَمِلُوا الصّٰلِحٰتِ وَ اَخۡبَتُوۡۤا اِلٰی رَبِّہِمۡ ۙ اُولٰٓئِکَ اَصۡحٰبُ الۡجَنَّۃِ ۚ ہُمۡ فِیۡہَا خٰلِدُوۡنَ"
string(183) "ان الذیۡن اٰمنوۡا و عملوا الصٰلحٰت و اخۡبتوۡۤا الٰی ربہمۡ ۙ اولٰئک اصۡحٰب الۡجنۃ ۚ ہمۡ فیۡہا خٰلدوۡن"
string(127) "ان الذن امنوا و عملوا الصلحت و اخبتوا ال ربم اولئ اصحب الجن م فا خلدون"同样,依赖explode()进行分词对于人类书写的文本来说通常是不可行的,因为它不尊重标点符号或其他非空格的分词。这是IntlBreakIterator的确切用例
function strip_arabic_diacritics($str) {
return strip_arabic_diacritics_2($str);
}
$br = IntlBreakIterator::createWordInstance();
$br->setText($str);
$output = '';
$ptr_stripped = strip_arabic_diacritics($ptr);
foreach($br->getPartsIterator() as $word) {
$word_stripped = strip_arabic_diacritics($word);
if( $ptr_stripped == $word_stripped ) {
$output .= sprintf('<span class="...">%s</span>', $word);
} else {
$output .= $word;
}
}
var_dump( $output );输出:
string(290) "اِنَّ الَّذِیۡنَ اٰمَنُوۡا وَ <span class="...">عَمِلُوا</span> الصّٰلِحٰتِ وَ اَخۡبَتُوۡۤا اِلٰی رَبِّہِمۡ ۙ اُولٰٓئِکَ اَصۡحٰبُ الۡجَنَّۃِ ۚ ہُمۡ فِیۡہَا خٰلِدُوۡنَ"由于RTL和LTR之间的切换,源字符串看起来有点不稳定,但是它应该正确地呈现。
https://stackoverflow.com/questions/67476968
复制相似问题