PHP - 字符串逻辑解析 - “X AND Y OR Z”
我想利用一个和/或未知长度的逻辑查询查询字符串:PHP - 字符串逻辑解析 - “X AND Y OR Z”
$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();
}
任何更好的办法来解决呢?
更新:增加了使用& &和||的能力。随时随地
你可以做到以下几点:
<?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"
}
}
如何:
$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);
有趣的是,最后一项是参考。 – user2362840 2013-05-08 15:26:59
这与Mark Baker的回答共享问题,清理0个条目(它们本质上是相同的答案),但它也有点“太简单”。例如,如果我想处理手动分组“x和(y或z)和一个”。在优雅和效率类别中获得肯定的胜利。 – user2362840 2013-05-08 15:42:40
@ user2362840 - 如果你想处理大括号,那么你使用了一个合适的词法分析器而不是简单的正则表达式......但是你并没有在你的原始问题中指出这一点。如果这是一项要求,那么答案会复杂得多 – 2013-05-08 15:46:32
使用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-08 15:10:57
g OR illas。 LOL – 2013-05-08 15:12:26
我忘了更改'或'为'或'后在爆炸:)后更新结果 – Alvaro 2013-05-08 15:12:30
这将处理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
进入
在array_filter警告好点。 – cmbuckley 2013-05-08 15:16:16
什么我想我会去:
$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);
没有括号布尔*语言*没有多大意义。 – hek2mgl 2013-05-08 15:00:45
在'或'上爆炸(')它会不会更容易,然后爆炸'和'上的每个片段?无可否认,这会给你一个空的数组,在你的样本字符串的末尾,你有“和和”,但你可以检查。 – andrewsi 2013-05-08 15:03:05
是“和和”结尾的错字吗? – 2013-05-08 15:05:51