9

我想采用未知长度的和/或逻辑查询查询字符串:

$logic = 'elephants and tigers or dolphins and apes or monkeys and humans and gorillas and and 133322 or 2';

并将其解析为一个数组,我假设它看起来像:

$parsed_to_or = array(
  array('elephants', 'tigers'),
  array('dolphins', 'apes'),
  array('monkeys', 'humans', 'gorillas', '133322'),
  array('2')
 );

这是我到目前为止所拥有的:

 $logic_e = preg_split('/\s+/', $logic); 
 $or_segments = array();
 $and_group = array();  
 foreach($logic_e as $fragment) {
  if (preg_match('/^(and|&&)$/i', $fragment)) {
   continue;
  } elseif (preg_match('/^(or|\\|\\|)$/i', $fragment)) {
   if (count($and_group)>0) {
    $or_segments[] = $and_group;
    $and_group = array();
   } continue;
  } else {
   $and_group[] = $fragment;
   continue;
  }
 } 
 if (count($and_group)>0) {
  $or_segments[] = $and_group;
  $and_group = array();
 }

有没有更好的方法来解决这个问题?

4

5 回答 5

4

更新:添加了使用 && 和 || 的功能 任何地方

您可以执行以下操作:

<?php

$logic = 'elephants && tigers || dolphins && apes || monkeys and humans and gorillas and && 133322 or 2';

$result = array();
foreach (preg_split('/ (or|\|\|) /', $logic) as $parts) {
  $bits = preg_split('/ (and|&&) /', $parts);
  for ($x=0; $x<count($bits); $x++) {
    $bits[$x] = preg_replace('/\s?(and|&&)\s?/', '', $bits[$x]);
  }
  $result[] = $bits;
}

echo '<pre>';
var_dump($result);

这将导致以下结果:

array(4) {
  [0]=>
  array(2) {
    [0]=>
    string(9) "elephants"
    [1]=>
    string(6) "tigers"
  }
  [1]=>
  array(2) {
    [0]=>
    string(8) "dolphins"
    [1]=>
    string(4) "apes"
  }
  [2]=>
  array(4) {
    [0]=>
    string(7) "monkeys"
    [1]=>
    string(6) "humans"
    [2]=>
    string(8) "gorillas"
    [3]=>
    string(6) "133322"
  }
  [3]=>
  array(1) {
    [0]=>
    string(1) "2"
  }
}
于 2013-05-08T15:03:07.840 回答
3

这将处理gorillas问题,以及空条目,例如and and

$logic = 'elephants and tigers or dolphins and apes || monkeys and humans and gorillas and and 133322 or 2';

$arrayBlocks = preg_split('/(\bor\b|\|\|)/', $logic);
array_walk(
    $arrayBlocks,
    function(&$entry, $key) {
        $entry = preg_split('/(\band\b|&&)/', $entry);
        $entry = array_filter(
            array_map(
                'trim',
                $entry
            )
        );
    }
);

var_dump($arrayBlocks);

虽然 array_filter 也会清理一个0条目

于 2013-05-08T15:09:31.930 回答
2

这个怎么样:

$logic = 'elephants and tigers or dolphins and apes or monkeys and humans and gorillas and and 133322 or 2';
$ors = preg_split('/(\bor\b|\s\|\|\s)/', $logic);

foreach ($ors as &$or) {
    $or = array_filter(array_map('trim', preg_split('/(\band\b|\s&&\s)/', $or)));
}

var_dump($ors);
于 2013-05-08T15:05:15.630 回答
1

使用explode要简单得多:

    $logic = 'elephants and tigers or dolphins and apes or monkeys and humans and gorillas and and 133322 or 2';

    $parts = explode(" or ", $logic);

    foreach($parts as $part){
        if(!empty($part)){
            $finalArray[] = explode(" and ", $part);

        }
    }

    print_r($finalArray);

那将返回:

Array
(
    [0] => Array
        (
            [0] => elephants
            [1] => tigers
        )

    [1] => Array
        (
            [0] => dolphins
            [1] => apes
        )

    [2] => Array
        (
            [0] => monkeys
            [1] => humans
            [2] => gorillas
            [3] => and 133322
        )

    [3] => Array
        (
            [0] => 2
        )

)
于 2013-05-08T15:06:03.680 回答
1

我想我会去:

$or_segments = array();
foreach(preg_split('/((\\s+or\\s+|\\s*\\|\\|\\s*))+/i', $logic) as $or_split_f) {        
 $or_segments[] = preg_split('/((\\s+and\\s+|\\s*&&\\s*))+/i', $or_split_f);
} 
var_dump($or_segments);
于 2013-05-08T17:58:06.300 回答