括号外用逗号引起的字符串爆炸

时间:2019-04-10 12:33:09

标签: php regex

我有一个想用逗号爆炸的字符串,但前提是逗号未嵌套在一些括号内。这是一个相当普遍的用例,我一直在阅读该论坛中的答复文章,但并未真正找到我想要的东西。

因此,详细来说:重点是,我有一个字符串(= 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? (因为我想用一个正则表达式行来处理,所以重点放在其中的正则表达式上),但是在我的小测试区域中,那些不能给出正确的结果。实际上,它们所有人都什么也没有分裂:

$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"));
?>

您可以想象,我不是正则表达式专家,但是如果可能的话,我想将其拆分为一行。

1 个答案:

答案 0 :(得分:0)

在此之后,我确实编写了解析器来解决此问题。这很丑陋,但确实可以做到(至少在某些限制内)。为了完整性(如果其他人可能遇到相同的问题),我将其发布在这里:

<form id='main'>

  <input type="checkbox" name="trigger" id='trigger' checked>

  <input type="checkbox" name="idArray[]" id="id1" value="1" checked>
  <input type="checkbox" name="idArray[]" id="id2" value="2" checked>
  <input type="checkbox" name="idArray[]" id="id3" value="3" checked>

</form>

使用以下字符串填充

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