-3

What is the best/easiest way to find a string (with PHP) inside a text with:

  • Any kind of special characters
  • String boundary (space)
  • Case insensitive

Some examples:

$text = "This is a test èsàdò string123?"; 
$find = "èsàDò"; 

Will return true

$text = "This is a test èsàdò string123?"; 
$find = "a TEST èsàdò";

Will return true

$text = "This is a test èsàdò string123?";
$find = "string123";

Will return true

$text = "This is a test èsàdò string123?";
$find = "string12";

Will return false

$text = "This is a test èsàdò string123?";
$find = "This is a test èsàdò String123?";

Will return true

Kianda
  • 23
  • 6

5 Answers5

0

Explode at your 'boundary'/delimiter, then loop over the array and return on the first match.

$array = explode(" ", $string);
foreach($array as $array_item){
    if (stripos($array_item, 'èsàdò') !== false) {
        return true;
     }
}
i-CONICA
  • 2,361
  • 9
  • 30
  • 45
0

You can use Regex functions like preg_match or preg_match_all

Example :

Sample : EDIT : (Thanks to Thomas Ghesquière who found a working pattern just below)

function test($string,$pattern){
   return (preg_match("/\b({$pattern})\b/ui","".trim($string)."",$res)) ? "Found" : "Not found";

}



$text = "This is a test èsàdò string123?"; 
$find = "èsàDò"; 
echo test($text,$find) . "\n";


$text = "This is a test èsàdò string123?"; 
$find = "a TEST èsàdò";
echo test($text,$find) . "\n";


$text = "This is a test èsàdò string123?";
$find = "string123";
echo test($text,$find) . "\n";


$text = "This is a test èsàdò string123?";
$find = "string12";
echo test($text,$find) . "\n";


$text = "This is a test èsàdò string123?";
$find = "This is a test èsàdò String123?";
echo test($text,$find) . "\n";  

will return true of false, depending on $text and $find. Here it will return true. http://php.net/manual/fr/function.preg-match.php

sizrar@ovador:~$ php test.php

Found

Found

Found

Not found

Found

You can see the results are nearly OK (still some tuning for your last example but th main principle is there) In this special case you could easily rule out the equality case in the testing function. But to determine what regular expression to use , you can use en online tester like : https://regex101.com/ and complète the first argument of preg_match accordingly

sizrar
  • 101
  • 1
  • 6
0

Use the \b word delimiter for your regular expressions and u for matching accented characters.

$text = "This is a test èsàdò string123?";
$find = "èsàDò";
// remove trailing punctuations from $find
// punctuations inside the string are not affected
$find = preg_replace('/([[:punct:]]+)$/iu', '', $find);
// escape any regex specific character
$find = preg_quote($find);

if (preg_match("/\b({$find})\b/ui", $text)) {
    echo "match";
} else {
    echo "no match";
}
0

Since you didn't define what you call a "boundary", I assumed (from your tests) it means that the searched substring can be surrounded with spaces, punctuation characters and limits of the string. To express that I used negative lookarounds:

  • (?<![^\s\pP]) (not preceded with a character that isn't a space or a punctuation character)
  • (?![^\s\pP]) (not followed with a character that isn't a space or a punctuation character)

Note that I used negative lookarounds (instead of (?<=[\s\pP]) and (?=[\s\pP])) to implicitly include cases where the searched string begins or ends at one of the limits of the string. In other words:

  • (?<![^\s\pP]) <=> (?<=[\s\pP]|^)
  • (?![^\s\pP]) <=> (?=[\s\pP]|$)

Code:

$text = 'This is a test èsàdò string123?'; 
$needles = ['èsàDò', 'a TEST èsàdò', 'string123', 'string12', 'This is a test èsàdò String123?'];

$format = " %-35s\t%s%s";
echo 'TEST STRING: ', $text, PHP_EOL, PHP_EOL;
printf($format, 'needle', 'result', PHP_EOL);
echo str_repeat('-', 50), PHP_EOL;

foreach ($needles as $needle) {
    $pattern = '~(?<![^\s\pP])' . preg_quote($needle, '~') . '(?![^\s\pP])~iu';
    printf($format, $needle, (preg_match($pattern, $text) ? 'true' : 'false'), PHP_EOL);
}

Result:

TEST STRING: This is a test èsàdò string123?

 needle                                 result
--------------------------------------------------
 èsàDò                                  true
 a TEST èsàdò                           true
 string123                              true
 string12                               false
 This is a test èsàdò String123?        true
Casimir et Hippolyte
  • 88,009
  • 5
  • 94
  • 125
-1

To match any of the following:

  • Any kind of special characters
  • String boundary (space)
  • Case insensitive

i would look into preg_match preg_match

using a regex you can then search for any string that matches special characters or string boudaries and if it is set with the i flag it will be case insensitive.

for example: preg_match("/([èsàDò\b]+)/i"'This is a test èsàdò string123?',$matches) this will retrieve any matches into the $matches array, or for just a boolean true/false:

if(preg_match("/[èsàDò\b]+/i"'This is a test èsàdò string123?')){
[CODE HERE]
}
Matt Nunn
  • 9
  • 7