Не удается найти допустимую скобку Regexp [duplicate]

Убедитесь, что mysqli_connect() создает соединение с БД. Вы можете использовать mysqli_errno() для проверки ошибок.

211
задан Noctis 7 June 2014 в 11:57
поделиться

12 ответов

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

Если вам нужно сопоставить соответствующие вложенные скобки, тогда вам нужно нечто большее, чем регулярные выражения. - см. @dehmann

Если он просто открыт для последнего закрытия, см. @Zach

Решите, что вы хотите, чтобы :

abc ( 123 ( foobar ) def ) xyz ) ghij

Вам нужно решить, что ваш код должен соответствовать в этом случае.

114
ответ дан Community 24 August 2018 в 23:04
поделиться

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

Здесь вы можете прочитать хорошую статью здесь . Вам также может потребоваться прочитать регулярные выражения .NET. Вы можете начать читать здесь .

Были использованы угловые скобки <>, потому что они не требуют экранирования.

Регулярное выражение выглядит следующим образом:

<
[^<>]*
(
    (
        (?<Open><)
        [^<>]*
    )+
    (
        (?<Close-Open>>)
        [^<>]*
    )+
)*
(?(Open)(?!))
>
14
ответ дан Alan Moore 24 August 2018 в 23:04
поделиться

Вы можете использовать рекурсию regex :

\(([^()]|(?R))*\)
69
ответ дан Amal Murali 24 August 2018 в 23:04
поделиться

Я хочу добавить этот ответ для быстрой ссылки. Невозможно обновить.


.NET Regex с использованием балансировочных групп .

\((?>\((?<c>)|[^()]+|\)(?<-c>))*(?(c)(?!))\)

Где c используется как счетчик глубины.

Демонстрация в Regexstorm.com


PCRE с использованием рекурсивного шаблона .

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

Демонстрация в regex101 ; Или без чередования:

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

Демо в regex101 ; Или разворачивается для исполнения:

\([^)(]*(?:(?R)[^)(]*)*+\)

Демонстрация в regex101 ; Рисунок наклеивается на (?R), который представляет (?0).

Perl, PHP, Notepad ++, R : perl = TRUE , Python : пакет Regex с (?V1) для поведения Perl.


Ruby с использованием вызовов подвыражения .

С Ruby 2.0 \g<0> можно использовать для вызова полного шаблона.

\((?>[^)(]+|\g<0>)*\)

Демоверсия в Rubular ; Ruby 1.9 поддерживает только рекурсию группы захвата группы :

(\((?>[^)(]+|\g<1>)*\))

Демо в Rubular & nbsp; ( атомная группировка с Ruby 1.9 .3)


JavaScript & nbsp; API :: XRegExp.matchRecursive

XRegExp.matchRecursive(str, '\\(', '\\)', 'g');

JS, Java и другие ароматы регулярных выражений без рекурсии до 2 уровня вложенности:

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

Демонстрация в regex101 . Более глубокое вложение нужно добавить к рисунку. Чтобы ускорить работу с несбалансированными скобками , снимите квантор +.


Java: интересная идея с использованием прямых ссылок by @jaytea .


Ссылка - Что означает это регулярное выражение?

60
ответ дан bobble bubble 24 August 2018 в 23:04
поделиться

Я написал небольшую библиотеку javascript, названную balanced , чтобы помочь с этой задачей, вы можете выполнить это, выполнив

balanced.matches({
    source: source,
    open: '(',
    close: ')'
});

, вы даже можете выполнять замены

balanced.replacements({
    source: source,
    open: '(',
    close: ')',
    replace: function (source, head, tail) {
        return head + source + tail;
    }
});

представляет собой более сложный и интерактивный пример JSFiddle

2
ответ дан Chad Scira 24 August 2018 в 23:04
поделиться

Это тоже работало

re.findall(r'\(.+\)', s)
0
ответ дан DataScienceStep 24 August 2018 в 23:04
поделиться
"""
Here is a simple python program showing how to use regular
expressions to write a paren-matching recursive parser.

This parser recognises items enclosed by parens, brackets,
braces and <> symbols, but is adaptable to any set of
open/close patterns.  This is where the re package greatly
assists in parsing. 
"""

import re


# The pattern below recognises a sequence consisting of:
#    1. Any characters not in the set of open/close strings.
#    2. One of the open/close strings.
#    3. The remainder of the string.
# 
# There is no reason the opening pattern can't be the
# same as the closing pattern, so quoted strings can
# be included.  However quotes are not ignored inside
# quotes.  More logic is needed for that....


pat = re.compile("""
    ( .*? )
    ( \( | \) | \[ | \] | \{ | \} | \< | \> |
                           \' | \" | BEGIN | END | $ )
    ( .* )
    """, re.X)

# The keys to the dictionary below are the opening strings,
# and the values are the corresponding closing strings.
# For example "(" is an opening string and ")" is its
# closing string.

matching = { "(" : ")",
             "[" : "]",
             "{" : "}",
             "<" : ">",
             '"' : '"',
             "'" : "'",
             "BEGIN" : "END" }

# The procedure below matches string s and returns a
# recursive list matching the nesting of the open/close
# patterns in s.

def matchnested(s, term=""):
    lst = []
    while True:
        m = pat.match(s)

        if m.group(1) != "":
            lst.append(m.group(1))

        if m.group(2) == term:
            return lst, m.group(3)

        if m.group(2) in matching:
            item, s = matchnested(m.group(3), matching[m.group(2)])
            lst.append(m.group(2))
            lst.append(item)
            lst.append(matching[m.group(2)])
        else:
            raise ValueError("After <<%s %s>> expected %s not %s" %
                             (lst, s, term, m.group(2)))

# Unit test.

if __name__ == "__main__":
    for s in ("simple string",
              """ "double quote" """,
              """ 'single quote' """,
              "one'two'three'four'five'six'seven",
              "one(two(three(four)five)six)seven",
              "one(two(three)four)five(six(seven)eight)nine",
              "one(two)three[four]five{six}seven<eight>nine",
              "one(two[three{four<five>six}seven]eight)nine",
              "oneBEGINtwo(threeBEGINfourENDfive)sixENDseven",
              "ERROR testing ((( mismatched ))] parens"):
        print "\ninput", s
        try:
            lst, s = matchnested(s)
            print "output", lst
        except ValueError as e:
            print str(e)
    print "done"
0
ответ дан Gene Olson 24 August 2018 в 23:04
поделиться

Это окончательное регулярное выражение:

\(
(?<arguments> 
(  
  ([^\(\)']*) |  
  (\([^\(\)']*\)) |
  '(.*?)'

)*
)
\)

Пример:

input: ( arg1, arg2, arg3, (arg4), '(pip' )

output: arg1, arg2, arg3, (arg4), '(pip'

обратите внимание, что '(pip' правильно управляется как строка. (проверено в регуляторе: http://sourceforge.net/projects/regulator/ )

3
ответ дан Marco 24 August 2018 в 23:04
поделиться

Регулярное выражение с использованием Ruby (версия 1.9.3 или выше):

/(?<match>\((?:\g<match>|[^()]++)*\))/

Демо на rubular

2
ответ дан nhahtdh 24 August 2018 в 23:04
поделиться

, так что вам нужна первая и последняя родительская головка, используйте smth, как этот str.indexOf ('('); - он даст вам первое появление str.lastIndexOf (')'); - last one

, так что вам нужна строка между, String searchString = str.substring (str1.indexOf ('('), str1.lastIndexOf (')');

1
ответ дан Shell Scott 24 August 2018 в 23:04
поделиться

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


Регулярные выражения не могут этого сделать.

Регулярные выражения основаны на вычислительной модели, известной как Finite State Automata (FSA). Как видно из названия, FSA может помнить только текущее состояние, оно не имеет информации о предыдущих состояниях.

На приведенной выше диаграмме , S1 и S2 - это два состояния, где S1 является начальным и конечным шагами. Поэтому, если мы попробуем со строкой 0110, переход будет выглядеть следующим образом:

      0     1     1     0
-> S1 -> S2 -> S2 -> S2 ->S1

В вышеприведенных шагах, когда мы находимся на втором S2, т.е. после разбора 01 в 0110 , FSA не имеет информации о предыдущем 0 в 01, так как он может только помнить текущее состояние и следующий входной символ.

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

Однако для достижения цели можно написать алгоритм. Алгоритмы обычно подпадают под Pushdown Automata (PDA). PDA на один уровень выше FSA. У КПК есть дополнительный стек, чтобы что-то хранить. КПК могут использоваться для решения вышеуказанной проблемы, потому что мы можем «push» открывать скобки в стеке и «pop» их, как только мы сталкиваемся с закрывающей скобкой. Если в конце стопка пуста, откроются скобки и закрывающая скобка. В противном случае нет.

Подробное обсуждение можно найти здесь здесь .

4
ответ дан Somnath Musib 24 August 2018 в 23:04
поделиться

Это настраиваемое решение, позволяющее использовать одиночные символьные литеральные разделители в Java:

public static List<String> getBalancedSubstrings(String s, Character markStart, 
                                 Character markEnd, Boolean includeMarkers) 

{
        List<String> subTreeList = new ArrayList<String>();
        int level = 0;
        int lastOpenDelimiter = -1;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            if (c == markStart) {
                level++;
                if (level == 1) {
                    lastOpenDelimiter = (includeMarkers ? i : i + 1);
                }
            }
            else if (c == markEnd) {
                if (level == 1) {
                    subTreeList.add(s.substring(lastOpenDelimiter, (includeMarkers ? i + 1 : i)));
                }
                if (level > 0) level--;
            }
        }
        return subTreeList;
    }
}

Использование образца:

String s = "some text(text here(possible text)text(possible text(more text)))end text";
List<String> balanced = getBalancedSubstrings(s, '(', ')', true);
System.out.println("Balanced substrings:\n" + balanced);
// => [(text here(possible text)text(possible text(more text)))]
1
ответ дан Wiktor Stribiżew 24 August 2018 в 23:04
поделиться
Другие вопросы по тегам:

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