我有一个要用逗号分解的字符串,但前提是逗号不嵌套在某些括号中。这是一个相当常见的用例,我一直在阅读这个论坛中的回复帖子,但并没有真正找到我想要的东西。
所以,详细地说:关键是,我有一个字符串(=sql select…from语句),我想从列表中提取元素,用逗号分隔,逗号编码在这个字符串中(=要从中选择的列的名称)。但是,这些元素可以包含方括号,并且实际上是函数调用。例如,在sql中

SELECT TO_CHAR(min(shippings.shippingdate), 'YYYY-MM-DD') as shippingdate, nameoftheguy FROM shippings WHERE ...

显然,我希望现在有一个数组作为第一个元素包含
TO_CHAR(min(shippings.shippingdate), 'YYYY-MM-DD') as shippingdate

作为第二要素
nameoftheguy

到目前为止,我采用的方法是
PHP and RegEx: Split a string by commas that are not inside brackets (and also nested brackets)
PHP: Split a string by comma(,) but ignoring anything inside square brackets?
Explode string except where surrounded by parentheses?,以及
PHP: split string on comma, but NOT when between braces or quotes?
(重点放在其中的regex表达式上,因为我想用一行regex来实现),但是在我的小测试区域中,这些并没有给出正确的结果。事实上,他们都没有分开或分开太多:
$Input: SELECT first, second, to_char(my,big,house) as bigly, export(mastermind and others) as aloah FROM
$Output: Array ( [0] => first [1] => second [2] => to_char [3] => (my,big,house) [4] => as [5] => bigly [6] => export [7] => (mastermind and others) [8] => as [9] => aloah )

我的测试区域代码是
<?php
function test($sql){
    $foo = preg_match("/SELECT(.*?)FROM/", $sql, $match);
    $bar = preg_match_all("/(?:[^(|]|\([^)]*\))+/", $match[1], $list);
    //$bar = preg_match_all("/\((?:[^()]|(?R))+\)|'[^']*'|[^(),\s]+/", $match[1], $list);
    //$bar = preg_match_all("/[,]+(?![^\[]*\])/", $match[1], $list);
    //$bar = preg_match_all("/(?:[^(|]|\([^)]*\))+/", $match[1], $list);
    //$bar = preg_match_all("/[^(,\s]+|\([^)]+\)/", $match[1], $list);
    //$bar = preg_match_all("/([(].*?[)])|(\w)+/", $match[1], $list);
    print "<br/>";
    return $list[0];
}

print_r(test("SELECT first, second, to_char(my,big,house) as bigly, export(mastermind and others) as aloah FROM"));
?>

你可以想象,我不是regex专家,但如果可能的话,我想把它分成一行。

最佳答案

在这里的对话之后,我编写了一个解析器来解决这个问题。它相当难看,但它确实起到了作用(至少在某些限制范围内)。为了完整起见(如果其他人可能会遇到同样的问题),我在这里发布:

function full($sqlu){
    $sqlu = strtoupper($sqlu);
    if(strpos($sqlu, "SELECT ")===false || strpos($sqlu, " FROM ")===false) return NULL;
    $def      = substr($sqlu, strpos($sqlu, "SELECT ")+7, strrpos($sqlu, " FROM ")-7);
    $raw      = explode(",", $def);
    $elements = array();
    $rem      = array();
    foreach($raw as $elm){
        array_push($rem, $elm);
        $txt = implode(",", $rem);
        if(substr_count($txt, "(") - substr_count($txt, ")") == 0){
            array_push($elements, $txt);
            $rem = array();
        }
    }
    return $elements;
}

当用下面的绳子喂它时
SELECT first, second, to_char(my,(big, and, fancy),house) as bigly, (SELECT myVar,foo from z) as super, export(mastermind and others) as aloah FROM table

它又回来了
Array ( [0] => first [1] => second [2] => to_char(my,(big, and, fancy),house) as bigly [3] => (SELECT myVar,foo from z) as super [4] => export(mastermind and others) as aloah )

关于php - 括号外用逗号引爆字符串,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55612680/

10-12 07:38
查看更多