Regex для проверки, если строка не соответствовала круглым скобкам?

git show HEAD@{0}

отлично работает для меня

17
задан twk 18 February 2009 в 20:35
поделиться

7 ответов

Regex не является правильным инструментом для задания. Просканируйте строку вручную.

Псевдокод:

depth = 0
for character in some_string:
    depth += character == '('
    depth -= character == ')'
    if depth < 0:
       break

if depth != 0:
   print "unmatched parentheses"
25
ответ дан 30 November 2019 в 10:13
поделиться

Согласитесь с тем, что это невозможно с REGEX. Вы могли сделать следующее, хотя:

<?php

$testStrings = array( 'This is (ok)', 'This (is) (ok)', 'This is )bad(', 'This is also (bad', 'This is (bad (too)' );

foreach( $testStrings as $string ) {
    $passed = hasMatchedParentheses( $string ) ? 'passed' : 'did not pass';
    echo "The string $string $passed the check for matching parenthesis.\n";
}

function hasMatchedParentheses( $string ) {
    $counter = 0;
    $length = strlen( $string );
    for( $i = 0; $i < $length; $i ++ ) {
        $char = $string[ $i ];
        if( $char == '(' ) {
            $counter ++;
        } elseif( $char == ')' ) {
            $counter --;
        }
        if( $counter < 0 ) {
            return false;
        }
    }
    return $counter == 0;
}

?>
4
ответ дан 30 November 2019 в 10:13
поделиться

Вы можете делать это с регулярным выражением - PCRE, как используется PHP, позволять рекурсивные шаблоны. Руководство PHP дает пример , который является почти точно, что Вы хотите:

\(((?>[^()]+)|(?R))*\)

Это соответствует любой правильно заключенной в скобки подстроке, пока она начинается и заканчивается круглыми скобками. Если Вы хотите удостовериться, что вся строка сбалансирована, позволив строки как "wiggedy (wiggedy) (wiggedy (ненормальный))", вот то, что я придумал:

^((?:[^()]|\((?1)\))*+)$

Вот объяснение шаблона, который может больше освещать, чем путанный:

^             Beginning of the string
(             Start the "balanced substring" group (to be called recursively)
  (?:         Start the "minimal balanced substring" group
    [^()]     Minimal balanced substring is either a non-paren character
    |         or
    \((?1)\)  a set of parens containing a balanced substring
  )           Finish the "minimal balanced substring" group
  *           Our balanced substring is a maximal sequence of minimal
              balanced substrings
  +           Don't backtrack once we've matched a maximal sequence
)             Finish the "balanced substring" pattern
$             End of the string

существует много соображений эффективности и правильности, которые придумывают эти виды regexes. Будьте осторожны.

21
ответ дан 30 November 2019 в 10:13
поделиться

Ваши примеры не включают, любой вложил parentheses†¦, если Вы не обеспокоены вложением, затем это может быть сделано с помощью следующего выражения:

^[^()]*(?:\([^()]*\)[^()]*)*$

Это будет соответствовать против всех строк в Вашем "позволять" список и сбой против строк в Вашем "предотвращать" список. Однако это также перестанет работать против любой строки с вложенными круглыми скобками . например, "это (не хорошо)"

, Поскольку другие уже указали, регулярные выражения не являются корректным инструментом, если необходимо обработать вложение.

3
ответ дан 30 November 2019 в 10:13
поделиться

Не возможно выполнить это с regex. Фигурная скобка, соответствующая, требует рекурсивной функции / функции подсчета, которая не доступна в regex. Вам будет нужен синтаксический анализатор для этого.

[еще 112] детали, доступные здесь: http://blogs.msdn.com/jaredpar/archive/2008/10/15/regular-expression-limitations.aspx

8
ответ дан 30 November 2019 в 10:13
поделиться

Для расширения ответа JaredPar не очень трудно решить, не используя regex, просто записать функцию, которая исследует каждый символ в строке и увеличивает/постепенно уменьшает счетчик. Если Вы находите" (", увеличивает это, и если Вы находите")", постепенно уменьшается это. Если счетчик когда-нибудь понижается 0, можно повредиться, строка недопустима. При обработке целой строки если счетчик не 0, была несопоставленная открывающая скобка.

2
ответ дан 30 November 2019 в 10:13
поделиться

, Почему это не возможно с regex

, другие ответы все корректны, но я просто хочу вставить разъем для теоретической информатики... это - случай, где знание теории дает фактическое практическое преимущество.

А regex соответствует детерминированному конечному автомату (DFA), но соответствие paren требует контекстно-свободной грамматики, которая может быть осознана как конечный автомат (КПК), но не DFA.

из-за этого, без большого количества дополнительной умственной деятельности, мы знаем, что ответ не, и мы не должны волноваться, что существует что-то, что мы просто пропускаем. Так, можно быть уверены в вышеупомянутых ответах и не волноваться, что авторы просто пропускают что-то, когда они дают тот ответ.

Почти все книги компилятора будут рассказывать об этом, вот быстрый обзор:

http://books.google.com/books?id=4LMtA2wOsPcC&pg=PA94&lpg=PA94&dq=push-down+finite+automata&source=bl&ots=NisYwNO1r0&sig=ajaSHFXwpPOWG8IfbcfKoqzS5Wk&hl=en&ei=m26cSdf6DZGYsAPB-6SsAg&sa=X&oi=book_result&resnum=6&ct=result

1
ответ дан 30 November 2019 в 10:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: