开发者

Boolean Search Processing in PHP for PostgreSQL

This seems like an obvious question but there does not appear to be an answer anywhere at the moment.

I am looking to attempt to process a search query to go into a postgresql full-text search with correct formatting using PHP. I am a bit of newbie to regular expressions and I just can't seem to work out where to start.

I am looking to take a query along the lines ofSomething AND ("Some Phrase" OR Some Other Phrase) and convert it to 'Something' & (('Some' & 'Phrase')|('Some' & 'Other' & 'Phrase'))

You may be able to point me to a library that does this, I can't seem to find one although开发者_开发百科 I imagine it is a common problem. Thanks for any help!


This code will parse the example as given and return the requested output. Be aware that it is somewhat brittle: You may need to validate the format of the expression to ensure that it is similar to the format you posted.

$input = 'Something AND ("Some Phrase" OR Some Other Phrase)';

$formatted_output = format_input( $input );

// Convert a query to a format suitable for a Postgres full-text search
function format_input( $input ) {
    $output = '';
    list ( $part1, $part2 ) = explode( 'AND', $input );

    // Remove any unecessary characters and add the first part of the line format
    $output = "'" . str_replace( array( "\"", "'" ), '', trim( $part1 ) ) . "' & (";

    // Get a list of phrases in the query
    $phrases = explode( 'OR', str_replace( array( '(', ')'), '', $part2 ) );

    // Format the phrase
    foreach ( $phrases as &$phrase ) {
        $phrase = encapsulate_phrase( trim ( str_replace( array( "\"", "'"), '', $phrase ) ) );
    }

    // Add the formatted phrases to the output
    $output .= '(' . implode( ')|(', $phrases ) . ')';

    // Add the closing parenthesis
    $output .= ')';

    return $output;
}

// Split a search phrase into words, and encapsulate the words
function encapsulate_phrase( $phrase ) {
    $output = '';
    $words = explode( ' ', trim( $phrase ) );

    // Remove leading and trailing whitespace, and encapsulate words in single quotes
    foreach ( $words as &$word ) {
        $word = "'" . trim( $word ) . "'";
    }

    // Add each word to the output
    $output .= implode (" & ", $words);


    return $output;
}

You can test your inputs like this:

$desired_output = "'Something' & (('Some' & 'Phrase')|('Some' & 'Other' & 'Phrase'))";

if ( !assert ( $formatted_output == $desired_output ) ) {
    echo "Desired: $desired_output\n";
    echo "Actual:  $formatted_output\n";
}
else {
    echo "Output: $formatted_output\n";
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜