How to use trim() for persian characters - php
Any help would be awesome thanks.
How to use this code for Persian characters?
function ae_filter_badword($content){
// filter badwords
$filter_word = ae_get_option('filter_keywords');
$filter_keywords = explode(',', $filter_word);
if(!empty($filter_keywords)){
foreach ($filter_keywords as $word) {
if($word){
$partern = '/\b' . trim($word) . '\b/i';
$content = preg_replace($partern, " ***", $content);
}
}
}
return $content;
}
I found the answer,Just use the following code
$partern = '/\b' . trim($word) . '\b/u';
u means utf-8
Related
Replace word in text between Tags
i know that there are many similar question but none have what im looking for, i need to replace a word from a text between tags but the problem is that is not having in account spaces or other wors so it doesnt match, I tried adding before comma the /b but is not working. Code Example: $content= preg_replace('#(?<=<p>)'.$value->data['target'].'(?=.*</p>)#', $value->data['string'], $content);
You can try to find the text between tags and replace it. You can try the following code: function replace_content_between_tags(string $content, string $tagname, string $searchStr, string $replaceWith) { $pattern = "#<\s*?$tagname\b[^>]*>(.*?)</$tagname\b[^>]*>#s"; preg_match_all($pattern, $content, $matches); foreach($matches[1] as $key => $match) { if(strpos($match, $searchStr) !== false) { $replaceContent = '<' . $tagname . '>' . $match . '</' . $tagname . '>'; $content = str_replace($replaceContent, $replaceWith, $content); break ; } } return $content; } $new_content = replace_content_between_tags($content, 'p', $value->data['target'], $value->data['string']);
Question about REGEX extracting text beetween
I'm trying in PHP to get something like this: $mail = "fakemail#le.mail.uk.test"; $rep = "le.mail"; I tried like this: function test($mail) { $pattern = '/^([\w-]+(?:\.[\w-]+)*)#((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/'; preg_match($pattern, $mail, $matches); echo $matches[2] . "\n"; } test("fakemail#le.mail.uk"); // result = le.mail but if i have another . in my mail it's broken function test($mail) { $pattern = '/^([\w-]+(?:\.[\w-]+)*)#((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/'; preg_match($pattern, $mail, $matches); echo $matches[2] . "\n"; } test("fakemail#le.mail.uk.test.test"); // result = le.mail.uk.test.test.test // whatIwant = le.mail or I just want all character between # and until the next .. I think I have to do a loop with an if but I'm not sure if it's possible with only regex.
A php way without REGEX, using implode() and explode() <?php $sep = '.'; $str1 = 'email#test.com.robot'; $str2 = 'email#test.fr.uk.robot'; $get1 = explode($sep,explode('#',$str1)[1]); $get2 = explode($sep,explode('#',$str2)[1]); echo implode($sep,[$get1[0],$get1[1]]); echo PHP_EOL; echo implode($sep,[$get2[0],$get2[1]]); ?> Output: test.com test.fr DEMO: https://3v4l.org/hJu52
Unexpected result using OR operator in regular expression
I've a problem with a regular expression. I have a text which is read from a file. The text can contain one or more IDs separated by comma. And then I have a list of IDs and want to check if one of these IDs match with my text so I try to use an OR operator: $idString = '2561,3,261,6,540,33,3105,2085,38,42,1066,49,3377,53,3161,91,356,3179,3695,3184,370,123,3451,124,3710,2188,141,404,1435,160,1443,432,435,440,1721,3261,2498,205,3282,476,482,3301,486,749,3309,243,3059,759,2046,4,262,785,534,541,3360,34,3106,2086,39,43,50,3378,54,1337,61,1351,3157,3162,360,3696,3185,631,3450,3200,666,1436,673,1444,3748,3262,2499,206,3279,3283,470,477,483,3302,490,755,760,2047,2562,1029,263,23,542,35,3107,2087,40,552,553,1321,47,51,3379,55,1338,3163,361,3697,3186,633,3452,639,143,3223,1445,3749,1450,3263,2500,207,3284,478,484,3303,2559,264,1297,22,543,36,44,57,1339,3389,62,3164,3677,362,3180,634,144,1685,1446,430,700,208,3286,479,1249,485,3306,2558,255,265,524,30,288,46,2095,63,2375,3165,403,1447,3242,696,1724,3557,3304,1770,3066,2563,266,544,2338,555,3131,3166,2204,415,1448,1239,3288,480,3305,754,267,545,3370,2378,3152,3170,648,147,679,1449,2537,753,2546,505,2564,3335,268,535,537,539,546,549,65,69,3167,148,3244,744,3068,2565,269,286,547,292,1334,1340,3659,3168,383,153,1705,3267,3060,2566,270,271,3099,548,1660,398,154,1706,2511,746,3332,2568,272,3148,422,3269,752,768,273,3381,3153,3199,155,468,784,274,3093,325,1657,3319,510,3329,3333,275,1432,2230,441,1722,773,3338,276,3641,2108,491,3339,277,2398,107,3181,2245,757,3346,2100,619,1760,2050,3351,2103,667,19,3372,2534,1064,351,1726,2394,2508,2538,2104,3147,2083,2097,2042,2096,2165,2049,2525,2526,1774,2392,2080,2043,2542,2547,2129,2540,2536,2190,2226,2569,2572,2373,2507'; $idString = str_replace(',', '|', $idString); $text = '1453,2018'; if (preg_match('/' . $idString . '/', $text)) { echo 'yes' . PHP_EOL; } else { echo 'no' . PHP_EOL; } I'm expecting that nothing matches because the IDs 1453 and 2018 are not found in my lookup string but it matches. I think that's because the ID 3 matches with 1453 but this is not correct for my use case.
That's too easy to work around it using arrays. You shouldn't use Regular Expressions if you can work with them but it seems this is not your real problem but an MCVE for a different one. You should use word boundaries \b otherwise a number like 4 is found in 1453. preg_match() third argument holds results to analyze what is going on. preg_match('/\b(?:' . $idString . ')\b/', $text, $match)
The syntax for preg_match is ($pattern, $text). Change it as follows, worked for me. <?php $idString = '2561,3,261,6,540,33,3105,2085,38,42,1066,49,3377,53,3161,91,356,3179,3695,3184,370,123,3451,124,3710,2188,141,404,1435,160,1443,432,435,440,1721,3261,2498,205,3282,476,482,3301,486,749,3309,243,3059,759,2046,4,262,785,534,541,3360,34,3106,2086,39,43,50,3378,54,1337,61,1351,3157,3162,360,3696,3185,631,3450,3200,666,1436,673,1444,3748,3262,2499,206,3279,3283,470,477,483,3302,490,755,760,2047,2562,1029,263,23,542,35,3107,2087,40,552,553,1321,47,51,3379,55,1338,3163,361,3697,3186,633,3452,639,143,3223,1445,3749,1450,3263,2500,207,3284,478,484,3303,2559,264,1297,22,543,36,44,57,1339,3389,62,3164,3677,362,3180,634,144,1685,1446,430,700,208,3286,479,1249,485,3306,2558,255,265,524,30,288,46,2095,63,2375,3165,403,1447,3242,696,1724,3557,3304,1770,3066,2563,266,544,2338,555,3131,3166,2204,415,1448,1239,3288,480,3305,754,267,545,3370,2378,3152,3170,648,147,679,1449,2537,753,2546,505,2564,3335,268,535,537,539,546,549,65,69,3167,148,3244,744,3068,2565,269,286,547,292,1334,1340,3659,3168,383,153,1705,3267,3060,2566,270,271,3099,548,1660,398,154,1706,2511,746,3332,2568,272,3148,422,3269,752,768,273,3381,3153,3199,155,468,784,274,3093,325,1657,3319,510,3329,3333,275,1432,2230,441,1722,773,3338,276,3641,2108,491,3339,277,2398,107,3181,2245,757,3346,2100,619,1760,2050,3351,2103,667,19,3372,2534,1064,351,1726,2394,2508,2538,2104,3147,2083,2097,2042,2096,2165,2049,2525,2526,1774,2392,2080,2043,2542,2547,2129,2540,2536,2190,2226,2569,2572,2373,2507'; $idString = str_replace(',', '|', $idString); $text = '1453,2018'; if (preg_match('/(' . $text . ')/', $idString)) { echo 'yes' . PHP_EOL; } else { echo 'no' . PHP_EOL; } ?>
You can see what gets matched by your Regex by outputting the matches, eg: if (preg_match('/' . $idString . '/', $text, $matches)) { echo 'yes' . PHP_EOL; print_r($matches); } else { echo 'no' . PHP_EOL; } You'd have to adapt your regex to match against whole words only... for example like this: if (preg_match('/\b(' . $idString . ')\b/', $text)) { https://regex101.com/r/M1Pieb/2/ Or you could avoid using regex altogether (recommended, its getting a bit crazy..) by using explode $idString = '2561,3,261,6,540,33,3105,2085,38,42,1066,49,3377,53,3161,91,356,3179,3695,3184,370,123,3451,124,3710,2188,141,404,1435,160,1443,432,435,440,1721,3261,2498,205,3282,476,482,3301,486,749,3309,243,3059,759,2046,4,262,785,534,541,3360,34,3106,2086,39,43,50,3378,54,1337,61,1351,3157,3162,360,3696,3185,631,3450,3200,666,1436,673,1444,3748,3262,2499,206,3279,3283,470,477,483,3302,490,755,760,2047,2562,1029,263,23,542,35,3107,2087,40,552,553,1321,47,51,3379,55,1338,3163,361,3697,3186,633,3452,639,143,3223,1445,3749,1450,3263,2500,207,3284,478,484,3303,2559,264,1297,22,543,36,44,57,1339,3389,62,3164,3677,362,3180,634,144,1685,1446,430,700,208,3286,479,1249,485,3306,2558,255,265,524,30,288,46,2095,63,2375,3165,403,1447,3242,696,1724,3557,3304,1770,3066,2563,266,544,2338,555,3131,3166,2204,415,1448,1239,3288,480,3305,754,267,545,3370,2378,3152,3170,648,147,679,1449,2537,753,2546,505,2564,3335,268,535,537,539,546,549,65,69,3167,148,3244,744,3068,2565,269,286,547,292,1334,1340,3659,3168,383,153,1705,3267,3060,2566,270,271,3099,548,1660,398,154,1706,2511,746,3332,2568,272,3148,422,3269,752,768,273,3381,3153,3199,155,468,784,274,3093,325,1657,3319,510,3329,3333,275,1432,2230,441,1722,773,3338,276,3641,2108,491,3339,277,2398,107,3181,2245,757,3346,2100,619,1760,2050,3351,2103,667,19,3372,2534,1064,351,1726,2394,2508,2538,2104,3147,2083,2097,2042,2096,2165,2049,2525,2526,1774,2392,2080,2043,2542,2547,2129,2540,2536,2190,2226,2569,2572,2373,2507'; $idStrings = explode(',', $idString); $values = ['1453', '2018']; $matchedValue = null; foreach ($values as $value) { if (in_array($value, $idStrings)) { $matchedValue = $value; break; } } if ($matchedValue !== null) { echo 'yes: ' . $matchedValue; } else { echo 'no'; }
How can I avoid adding href to an overlapping keyword in string?
Using the following code: $text = "أطلقت غوغل النسخة المخصصة للأجهزة الذكية العاملة بنظام أندرويد من الإصدار “25″ لمتصفحها الشهير كروم.ولم تحدث غوغل تطبيق كروم للأجهزة العاملة بأندرويد منذ شهر تشرين الثاني العام الماضي، وهو المتصفح الذي يستخدمه نسبة 2.02% من أصحاب الأجهزة الذكية حسب دراسة سابقة. "; $tags = "غوغل, غوغل النسخة, كروم"; $tags = explode(",", $tags); foreach($tags as $k=>$v) { $text = preg_replace("/\b{$v}\b/u","$0",$text, 1); } echo $text; Will give the following result: I love PHP">love PHP</a>, but I am facing a problem Note that my text is in Arabic.
The way is to do all in one pass. The idea is to build a pattern with an alternation of tags. To make this way work, you must before sort the tags because the regex engine will stop at the first alternative that succeeds (otherwise 'love' will always match even if it is followed by 'php' and 'love php' will never be matched). To limit the replacement to the first occurence of each word you can remove tag from the array once it has been found and you test if it is always present in the array inside the replacement callback function: $text = 'I love PHP, I love love but I am facing a problem'; $tagsCSV = 'love, love php, facing'; $tags = explode(', ', $tagsCSV); rsort($tags); $tags = array_map('preg_quote', $tags); $pattern = '/\b(?:' . implode('|', $tags) . ')\b/iu'; $text = preg_replace_callback($pattern, function ($m) use (&$tags) { $mLC = mb_strtolower($m[0], 'UTF-8'); if (false === $key = array_search($mLC, $tags)) return $m[0]; unset($tags[$key]); return '<a href="index.php?s=news&tag=' . rawurlencode($mLC) . '">' . $m[0] . '</a>'; }, $text); Note: when you build an url you must encode special characters, this is the reason why I use preg_replace_callback instead of preg_replace to be able to use rawurlencode. If you have to deal with an utf8 encoded string, you need to add the u modifier to the pattern and you need to replace strtolower with mb_strtolower) the preg_split way $tags = explode(', ', $tagsCSV); rsort($tags); $tags = array_map('preg_quote', $tags); $pattern = '/\b(' . implode('|', $tags) . ')\b/iu'; $items = preg_split($pattern, $text, -1, PREG_SPLIT_DELIM_CAPTURE); $itemsLength = count($items); $i = 1; while ($i<$itemsLength && count($tags)) { if (false !== $key = array_search(mb_strtolower($items[$i], 'UTF-8'), $tags)) { $items[$i] = '<a href="index.php?s=news&tag=' . rawurlencode($tags[$key]) . '">' . $items[$i] . '</a>'; unset($tags[$key]); } $i+=2; } $result = implode('', $items);
Instead of calling preg_replace multiple times, call it a single time with a regexp that matches any of the tags: $tags = explode(",", tags); $tags_re = '/\b(' . implode('|', $tags) . ')\b/u'; $text = preg_replace($tags_re, '$0', $text, 1); This turns the list of tags into the regexp /\b(love|love php|facing)\b/u. x|y in a regexp means to match either x or y.
str_ireplace not working with German characters
I am using the following function to search for words and color them inside a text. It works perfectly except for German characters (ä, ë, ß, etc). I already tried to encode to utf, decode, checked my meta tags and everything else like that but the problem is not the encoding as they show correctly on the site, they're just not "colored" by this function: function highlight($keyword, $input, $linktext, $color){ $text = $input; $word = $keyword; $text = str_ireplace(" ".$word, ' <span id="">' . $word . '</span>', $text); $iteration = 1; while (true) { $text = preg_replace('/<span.id="">' . $word . '<\/span>/imsxU', '<span style="background:'.$color.'" class="keyword" id="link' . $iteration . "\" onclick=\"setLink2('$keyword','$linktext',$iteration)\">" . $word . '</span>', $text, 1, $count); if (!$count) { break; } $y++; $iteration++; } return $text; } Any idea of how can I achieve this? I also tried to replace them but the German words should apear as they are on the text so that's a no go =/
as str_ functions in PHP do not support UTF, you have to use the mb_ extension. In your case, replace str_ireplace with mb_eregi_replace