Missing parentheses with Regex

后端 未结 4 946
轮回少年
轮回少年 2020-12-29 14:21

Am I correct in thinking that Regex can\'t be used to detect missing parentheses (because there is no way of counting pairs)? Using JavaScript I\'ve about a thousand strings

4条回答
  •  孤独总比滥情好
    2020-12-29 15:14

    It's possible to use recursive regex to verify matching parentheses. For example, in Perl, the following expression matches strings with proper () {} [] nesting:

    $r = qr/(?:(?>[^(){}\[\]]+)|\((??{$r})\)|\{(??{$r})\}|\[(??{$r})\])*/;
    

    Here is the same expression expanded for clarity:

    $r = qr/
        (?:
            (?>
                [^(){}\[\]]+
            )
        |
            \(
                (??{$r})
            \)
        |
            \{
                (??{$r})
            \}
        |
            \[
                (??{$r})
            \]
        )*
    /x;
    

    The outer group is quantified with * instead of + so as to match empty strings, so in order to make $r useful, the actual matching must be done with an expression that utilizes lookaheads/lookbehinds or otherwise establishes context, e.g. /^$r$/. For example, the following prints only the lines in a file that do not have proper nesting:

    perl -ne '$r = qr/(?:(?>[^(){}\[\]]+)|\((??{$r})\)|\{(??{$r})\}|\[(??{$r})\])*/; print if !m/^$r$/' file
    

    To address your clarification: If these are filenames and not file contents, you could pipe the output of ls or find or whatever into the above command, sans file:

    ls | perl -ne '$r = qr/(?:(?>[^(){}\[\]]+)|\((??{$r})\)|\{(??{$r})\}|\[(??{$r})\])*/; print if !m/^$r$/'
    

    However, as others have said, a non-regex solution is probably better in general.

    N.B. From the Perl doc: "WARNING: This extended regular expression feature is considered experimental, and may be changed without notice. Code executed that has side effects may not perform identically from version to version due to the effect of future optimisations in the regex engine."

提交回复
热议问题