首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用RegEx突出显示阿拉伯文本

使用RegEx突出显示阿拉伯文本
EN

Stack Overflow用户
提问于 2021-05-10 19:59:51
回答 2查看 192关注 0票数 0

我的数据库里有阿拉伯文,上面写着对话/塔什基尔。要搜索没有diacritics/tashkeel的用户类型,我和我可以使用全文搜索语句成功搜索,但不能使用正则表达式突出显示搜索词:

代码语言:javascript
运行
复制
$str="اِنَّ الَّذِیۡنَ اٰمَنُوۡا وَ عَمِلُوا الصّٰلِحٰتِ وَ اَخۡبَتُوۡۤا اِلٰی رَبِّہِمۡ ۙ اُولٰٓئِکَ اَصۡحٰبُ الۡجَنَّۃِ ۚ ہُمۡ فِیۡہَا خٰلِدُوۡنَ";

$ptr="عملوا";

$result = preg_replace("/$ptr/", '<span style="background:yellow">' . $ptr . '</span>', $str);

echo $result;

对如何解决这个问题有什么想法吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-05-10 22:12:43

您的字符串具有额外的字符,如tashkil。但是您想要匹配的字符没有tashkil,所以解决方案是替换额外的字符,并使两个字符串相似。

代码语言:javascript
运行
复制
<?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;

票数 0
EN

Stack Overflow用户

发布于 2021-05-10 23:58:32

虽然@Artier的答案可能是可以接受的,但在源代码中使用松散的UTF-8组合标记并不是最好的主意,而且,从我从Google收集到的信息来看,它们可能没有涵盖所有阿拉伯语的数字符号/组合标记。

免责声明:我对阿拉伯语知之甚少,但我对UTF-8很挑剔.

@Artier的答案似乎是从this question上接受的答案中筛选出来的,但接受的答案往往不是最佳的解决方案。来自同一组答案的另外两个选项之一很可能更接近规范正确。

代码语言:javascript
运行
复制
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)
);

输出:

代码语言:javascript
运行
复制
string(265) "اِنَّ الَّذِیۡنَ اٰمَنُوۡا وَ عَمِلُوا الصّٰلِحٰتِ وَ اَخۡبَتُوۡۤا اِلٰی رَبِّہِمۡ ۙ اُولٰٓئِکَ اَصۡحٰبُ الۡجَنَّۃِ ۚ ہُمۡ فِیۡہَا خٰلِدُوۡنَ"
string(183) "ان الذیۡن اٰمنوۡا و عملوا الصٰلحٰت و اخۡبتوۡۤا الٰی ربہمۡ ۙ اولٰئک اصۡحٰب الۡجنۃ ۚ ہمۡ فیۡہا خٰلدوۡن"
string(127) "ان الذن امنوا و عملوا الصلحت و اخبتوا ال ربم  اولئ اصحب الجن  م فا خلدون"

同样,依赖explode()进行分词对于人类书写的文本来说通常是不可行的,因为它不尊重标点符号或其他非空格的分词。这是IntlBreakIterator的确切用例

代码语言:javascript
运行
复制
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 );

输出:

代码语言:javascript
运行
复制
string(290) "اِنَّ الَّذِیۡنَ اٰمَنُوۡا وَ <span class="...">عَمِلُوا</span> الصّٰلِحٰتِ وَ اَخۡبَتُوۡۤا اِلٰی رَبِّہِمۡ ۙ اُولٰٓئِکَ اَصۡحٰبُ الۡجَنَّۃِ ۚ ہُمۡ فِیۡہَا خٰلِدُوۡنَ"

由于RTL和LTR之间的切换,源字符串看起来有点不稳定,但是它应该正确地呈现。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67476968

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档