3

Looking fo possibility to detect if $string is match all words in $array. Words order not known in advance (user typed text).

array(
  'test',
  'shmest',
  'zest',
  'fest',
  'etcest'
);

I undertand that i can:

$is_match = true;
foreach ($array as $word) {
  if (!strpos($string, $word) === false) {
    $is_match = false;
    break;
  }
}

(Can|Should) i make somethin like above via preg_match[_all]?

EDIT1

Priority is less memory and fast work.

Tested 2 unswers and own above https://eval.in/144266 so my is fastest

And $string can contain of any symbols

Subdigger
  • 2,166
  • 3
  • 20
  • 42
  • What is your input and what will be the match ? – Shankar Narayana Damodaran Apr 30 '14 at 06:53
  • check if it helps you http://stackoverflow.com/questions/7575899/php-in-array-find-any-matches – user3470953 Apr 30 '14 at 06:53
  • input somthing like: 'lets zest from the test and shmest of the etcest like fest' - should be true. if one of the words a missing in the string - false – Subdigger Apr 30 '14 at 06:55
  • @www.sblog.in nope. I`m not looking word `in_array` but all words in array exists in the string – Subdigger Apr 30 '14 at 06:57
  • Quote [from the PHP website](http://de3.php.net/manual/en/function.preg-match.php): `Tip: Do not use preg_match() if you only want to check if one string is contained in another string. Use strpos() or strstr() instead as they will be faster.` – Gerald Schneider Apr 30 '14 at 08:27
  • I have my doubts as to whether anything involving PCRE would be faster or more memory efficient. For a very large haystack and/or a very large number of needles it *might* be faster (especially when the same regex is used repeatedly in a single script), but it certainly won't be more memory efficient. To improve on what you have you probably want to be looking at some kind of hybrid boyer-moore algorithm that can handle multiple needles - which is unlikely to make a difference when implemented in userland PHP. Either way, I suspect this is a micro-optimisation (borne out by your test results). – DaveRandom Apr 30 '14 at 08:39
  • This question appears to be off-topic because it is more suited for http://codereview.stackexchange.com/ – Gerald Schneider Apr 30 '14 at 08:47

2 Answers2

3

You can create a RegEx with LookAheads:

$regex='/(?=.*?'.implode(')(?=.*?', $needles).')/s';

then simple check against your string:

if (preg_match($regex,$string)===1) echo 'true';

Demo code: https://eval.in/144296
Explained RegEx: http://regex101.com/r/eQ0hU4

CSᵠ
  • 10,049
  • 9
  • 41
  • 64
  • Great answer, but it returns `true` when `$needles` has a word that's is not presented in `$string` – el Dude Nov 07 '16 at 20:31
  • @elDude unable to replicate your exception, can you drop by in [regex room](http://chat.stackoverflow.com/rooms/25767/regex-regular-expressions) to clarify this? – CSᵠ Nov 12 '16 at 05:39
2

Use preg_split() and array_intersect():

$words = preg_split("/(?<=\w)\b\s*/", $input, -1, PREG_SPLIT_NO_EMPTY);
echo (array_intersect($arr, $words) == $arr) ? 'True' : 'False';

Basically preg_split() splits your input string into an array of words. array_intersect() checks if all the elements in $arr are present in $words.

Demo

Amal Murali
  • 75,622
  • 18
  • 128
  • 150