简体   繁体   English

如何通过正则表达式匹配多个括号外的逗号

[英]How to match comma outside multiple parentheses by regex

I split a string by comma, but not within parathesis, using preg_split .我使用preg_split用逗号分隔字符串,但不在括号内。 I came up with我想出了

preg_split('#,(?![^\(]*[\)])#',$str);

which works perfectly unless there is a comma before a nested parenthesis.除非嵌套括号前有逗号,否则它可以完美地工作。

Works for效劳于

$str = "first (1,2),second (child (nested), child2), third";

Array
(
    [0] => first (1,2)
    [1] => second (child (nested), child2)
    [2] =>  third
)

but not for但不是为了

$str = "first (1,2),second (child, (nested), child2), third";

Array
(
    [0] => first (1,2)
    [1] => second (child
    [2] =>  (nested), child2)
    [3] =>  third
)

Looking at the requirement of ignoring , which are inside the brackets, this problem just boils down to making sure the brackets are balanced.看看括号内的忽略要求,这个问题归结为确保括号是平衡的。 If any , resides inside an unbalanced parenthesis , we ignore them, else that , is our delimiter now for the split.如果有,位于不平衡的括号内,我们将忽略它们,否则,是我们现在用于拆分的分隔符。

To collect strings in-between these , , we maintain a start pointer $sub_start to keep track of substrings' start index and update them after we come across a valid delimiter , .为了收集这些,之间的字符串,我们维护一个起始指针$sub_start来跟踪子字符串的起始索引,并在遇到有效分隔符,后更新它们。

Snippet:片段:

<?php

function splitCommaBased($str){
    $open_brac = 0;
    $len = strlen($str);
    $res = [];
    $sub_start = 0;
    
    for($i = 0; $i < $len; ++$i){
        if($str[ $i ] == ',' && $open_brac == 0){
            $res[] = substr($str, $sub_start, $i - $sub_start);
            $sub_start = $i + 1;
        }else if($str[ $i ] == '('){
            $open_brac++;
        }else if($str[ $i ] == ')'){
            $open_brac--;
        }else if($i === $len - 1){
            $res[] = substr($str, $sub_start);
        }
    }
    
    return $res;
}

print_r(splitCommaBased('first (1,2),second (child, (nested), child2), third'));

You can use recursion matching the balanced parenthesis.您可以使用匹配平衡括号的递归。 Then make use of SKIP FAIL and match the comma to split on.然后使用 SKIP FAIL 并匹配要拆分的逗号。

(\((?:[^()]++|(?1))*\))(*SKIP)(*F)|,

See a regex demo .查看正则表达式演示

Example例子

$str = "first (1,2),second (child, (nested), child2), third";
$pattern = "/(\((?:[^()]++|(?1))*\))(*SKIP)(*F)|,/";
print_r(preg_split($pattern, $str));

Output Output

Array
(
    [0] => first (1,2)
    [1] => second (child, (nested), child2)
    [2] =>  third
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM