7

I want to create a PHP search function, but using Google-like operators. For instance:

these words "this phrase" location:"Los Angeles" operator:something

It's important that operators like location: support values with spaces in them (hence the quotes in this example), so I can't just to a split or use standard tokens. I'd imagine someone at some point has created a library for doing this, but I can't find any.

Or if it doesn't require a library, a nice way to do this would be good.

It's just the parsing of a search query that I need; i.e. from the query above it would be fine to get an array consisting of:

[0] => these
[1] => words
[2] => "this phrase"
[3] => location:"Los Angeles"
[4] => operator:something

From that I can build a search function for the database.

Rsaesha
  • 1,104
  • 1
  • 13
  • 25
  • how about separate inputs for "location, "operator" etc –  Mar 03 '13 at 21:57
  • [PHP explode the string, but treat words in quotes as a single word](http://stackoverflow.com/questions/2202435/php-explode-the-string-but-treat-words-in-quotes-as-a-single-word) – Wesley Murch Mar 03 '13 at 21:58
  • @Dagon I'd rather have it all in one query. – Rsaesha Mar 03 '13 at 22:24
  • @WesleyMurch That regex doesn't work for me. It splits up the location:"Los Angeles" into 'location:"Los' and 'Angeles"' – Rsaesha Mar 03 '13 at 22:25
  • @Rsaesha Yep you're right, and the [`str_getcsv` answer](http://stackoverflow.com/a/6609509/398242) does not seem to work either. – Wesley Murch Mar 03 '13 at 22:28

1 Answers1

14

You can start with str_getcsv() and use a space as the delimiter, but you may have to preprocess the location & operator to handle the quotes in that particular case.

<?php
$str = 'these words "this phrase" location:"Los Angeles" operator:something';

// preprocess the cases where you have colon separated definitions with quotes
// i.e. location:"los angeles"
$str = preg_replace('/(\w+)\:"(\w+)/', '"${1}:${2}', $str);

$str = str_getcsv($str, ' ');

var_dump($str);
?>

output

array(5) {
  [0]=>
  string(5) "these"
  [1]=>
  string(5) "words"
  [2]=>
  string(11) "this phrase"
  [3]=>
  string(20) "location:Los Angeles"
  [4]=>
  string(18) "operator:something"
}
Coder1
  • 13,139
  • 15
  • 59
  • 89
  • Hmm, that gives me the following array: [0] => these, [1] => words, [2] => this phrase, [3] => location:"Los, [4] => Angeles", [5] => operator:something – Rsaesha Mar 03 '13 at 22:19
  • I indicated there would be preprocess logic needed. I added a simple preprocess regex. – Coder1 Mar 03 '13 at 22:31
  • Awesome! This works really well, and was just what I was looking for. – Rsaesha Mar 03 '13 at 22:33
  • I would kiss you if I could. I HATE regex. Never could memorize the patterns. Now I have to deal with GLOB. Urgh... This allowed me to avoid spedning hours trying to compose the right regex. THANK YOU! – Derek Foulk Oct 15 '15 at 22:55