Значение между открывающей и закрывающей скобками [дубликат]

onInputMove не является методом обратного вызова. Поэтому вам нужно сделать что-то вроде:

  var event = function (ev) {self.onInputMove (ev)};  someDom.addEventListener ('mousemove', event, false);  someDom.removeEventListener ('mousemove', event, false);   
11
задан Cinco 28 March 2011 в 04:22
поделиться

12 ответов

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

Решение состоит в том, чтобы не использовать регулярные выражения. Если вы на самом деле пытаетесь разобрать математические выражения, используйте реальные решения синтаксического анализа. Если вы действительно хотите захватить фигуры в круглых скобках, просто зациклируйте символы, подсчитывая, когда вы видите (и), и увеличиваете декремент счетчика.

13
ответ дан Winston Ewert 17 August 2018 в 08:40
поделиться

Вы должны написать правильный синтаксический анализатор для синтаксического анализа такого выражения (например, с помощью pyparsing). Регулярные выражения не являются подходящим инструментом для написания достойных парсеров.

0
ответ дан Andreas Jung 17 August 2018 в 08:40
поделиться
  • 1
    Я принял ваш ответ близко к сердцу и написал то, что я консервативно называю «Моя первая пирамидальная грамматика». – phooji 28 March 2011 в 05:18

Стек - лучший инструмент для задания: -

import re
def matches(line, opendelim='(', closedelim=')'):
    stack = []

    for m in re.finditer(r'[{}{}]'.format(opendelim, closedelim), line):
        pos = m.start()

        if line[pos-1] == '\\':
            # skip escape sequence
            continue

        c = line[pos]

        if c == opendelim:
            stack.append(pos+1)

        elif c == closedelim:
            if len(stack) > 0:
                prevpos = stack.pop()
                # print("matched", prevpos, pos, line[prevpos:pos])
                yield (prevpos, pos, len(stack))
            else:
                # error
                print("encountered extraneous closing quote at pos {}: '{}'".format(pos, line[pos:] ))
                pass

    if len(stack) > 0:
        for pos in stack:
            print("expecting closing quote to match open quote starting at: '{}'"
                  .format(line[pos-1:]))

В клиентском коде, поскольку функция записывается как функция генератора, просто используйте шаблон for loop для разворачивания совпадений: -

line = '(((1+0)+1)+1)'
for openpos, closepos, level in matches(line):
    print(line[openpos:closepos], level)

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

1+0 2
(1+0)+1 1
((1+0)+1)+1 0
5
ответ дан Benny Khoo 17 August 2018 в 08:40
поделиться

Вот демо для вашего вопроса, хотя оно неуклюжие, пока оно работает

import re s = '(((1+0)+1)+1)'

def getContectWithinBraces( x , *args , **kwargs):
    ptn = r'[%(left)s]([^%(left)s%(right)s]*)[%(right)s]' %kwargs
    Res = []
    res = re.findall(ptn , x)
    while res != []:
        Res = Res + res
        xx = x.replace('(%s)' %Res[-1] , '%s')
        res = re.findall(ptn, xx)
        print(res)
        if res != []:
            res[0] = res[0] %('(%s)' %Res[-1])
    return Res

getContectWithinBraces(s , left='\(\[\{' , right = '\)\]\}')
0
ответ дан Chen 17 August 2018 в 08:40
поделиться
-1
ответ дан Community 17 August 2018 в 08:40
поделиться
0
ответ дан Esteban Martinez 17 August 2018 в 08:40
поделиться

Языки регексов недостаточно эффективны для сопоставления произвольно вложенных конструкций. Для этого вам нужен пусковой автомат (т. Е. Синтаксический анализатор). Доступно несколько таких инструментов, таких как PLY .

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

>>> import parser, pprint
>>> pprint.pprint(parser.st2list(parser.expr('(((1+0)+1)+1)')))
[258,
 [327,
  [304,
   [305,
    [306,
     [307,
      [308,
       [310,
        [311,
         [312,
          [313,
           [314,
            [315,
             [316,
              [317,
               [318,
                [7, '('],
                [320,
                 [304,
                  [305,
                   [306,
                    [307,
                     [308,
                      [310,
                       [311,
                        [312,
                         [313,
                          [314,
                           [315,
                            [316,
                             [317,
                              [318,
                               [7, '('],
                               [320,
                                [304,
                                 [305,
                                  [306,
                                   [307,
                                    [308,
                                     [310,
                                      [311,
                                       [312,
                                        [313,
                                         [314,
                                          [315,
                                           [316,
                                            [317,
                                             [318,
                                              [7,
                                               '('],
                                              [320,
                                               [304,
                                                [305,
                                                 [306,
                                                  [307,
                                                   [308,
                                                    [310,
                                                     [311,
                                                      [312,
                                                       [313,
                                                        [314,
                                                         [315,
                                                          [316,
                                                           [317,
                                                            [318,
                                                             [2,
                                                              '1']]]]],
                                                         [14,
                                                          '+'],
                                                         [315,
                                                          [316,
                                                           [317,
                                                            [318,
                                                             [2,
                                                              '0']]]]]]]]]]]]]]]],
                                              [8,
                                               ')']]]]],
                                          [14,
                                           '+'],
                                          [315,
                                           [316,
                                            [317,
                                             [318,
                                              [2,
                                               '1']]]]]]]]]]]]]]]],
                               [8, ')']]]]],
                           [14, '+'],
                           [315,
                            [316,
                             [317,
                              [318, [2, '1']]]]]]]]]]]]]]]],
                [8, ')']]]]]]]]]]]]]]]],
 [4, ''],
 [0, '']]

Вы можете облегчить боль этой короткой функцией:

def shallow(ast):
    if not isinstance(ast, list): return ast
    if len(ast) == 2: return shallow(ast[1])
    return [ast[0]] + [shallow(a) for a in ast[1:]]

>>> pprint.pprint(shallow(parser.st2list(parser.expr('(((1+0)+1)+1)'))))
[258,
 [318,
  '(',
  [314,
   [318, '(', [314, [318, '(', [314, '1', '+', '0'], ')'], '+', '1'], ')'],
   '+',
   '1'],
  ')'],
 '',
 '']

Числа поступают из модулей Python symbol и token, которые вы можете использовать для построения таблицы поиска из чисел в имена:

map = dict(token.tok_name.items() + symbol.sym_name.items())

Вы даже можете свернуть это сопоставление в shallow(), чтобы вы могли работать со строками вместо чисел:

def shallow(ast):
    if not isinstance(ast, list): return ast
    if len(ast) == 2: return shallow(ast[1])
    return [map[ast[0]]] + [shallow(a) for a in ast[1:]]

>>> pprint.pprint(shallow(parser.st2list(parser.expr('(((1+0)+1)+1)'))))
['eval_input',
 ['atom',
  '(',
  ['arith_expr',
   ['atom',
    '(',
    ['arith_expr',
     ['atom', '(', ['arith_expr', '1', '+', '0'], ')'],
     '+',
     '1'],
    ')'],
   '+',
   '1'],
  ')'],
 '',
 '']
11
ответ дан Marcelo Cantos 17 August 2018 в 08:40
поделиться
  • 1
    Я бы сказал, что PLY лучше подходит для больших задач синтаксического анализа. Я нашел его наиболее полезным, когда мне действительно нужно было подражать существующему парсера Lex / Yacc. Что касается использования встроенной библиотеки парсеров python ... hmph. – phooji 28 March 2011 в 05:06
  • 2
    @phooji: Я согласен. Библиотека парсеров Python определенно не для всех. – Marcelo Cantos 28 March 2011 в 06:47

Я считаю, что эта функция может удовлетворить вашу потребность, я быстро выбросил ее, поэтому не стесняйтесь немного ее очистить. При выполнении гнезд легко думать об этом назад и работать оттуда =]

def fn(string,endparens=False):
    exp = []
    idx = -1
    for char in string:
        if char == "(":
            idx += 1
            exp.append("")
        elif char == ")":
            idx -= 1
            if idx != -1:
                exp[idx] = "(" + exp[idx+1] + ")"
        else:
            exp[idx] += char
    if endparens:
        exp = ["("+val+")" for val in exp]
    return exp
-1
ответ дан Michael Gillette 17 August 2018 в 08:40
поделиться
  • 1
    Я ценю настроение, да, его хромая, чтобы использовать подробную функцию, предоставит запрошенный список. простите, если мой ответ не соответствует утилите @phooji, но я сомневаюсь, что здесь нужен неадекватный модуль синтаксического анализа. хотя я изучил целую тонну анализа из приведенных выше примеров с письменными описаниями. – Michael Gillette 28 March 2011 в 05:07
  • 2
    @pynator: меня смущает семантическая структура вашего комментария, но я думаю, что согласен :) – phooji 28 March 2011 в 05:09

Существует новый регулярный модуль двигателя , готовый заменить существующий в Python. Он вводит много новых функций, включая рекурсивные вызовы.

import regex

s = 'aaa(((1+0)+1)+1)bbb'

result = regex.search(r'''
(?<rec> #capturing group rec
 \( #open parenthesis
 (?: #non-capturing group
  [^()]++ #anyting but parenthesis one or more times without backtracking
  | #or
   (?&rec) #recursive substitute of group rec
 )*
 \) #close parenthesis
)
''',s,flags=regex.VERBOSE)


print(result.captures('rec'))

Выход:

['(1+0)', '((1+0)+1)', '(((1+0)+1)+1)']

Связанная ошибка в regex: http: // код. google.com/p/mrab-regex-hg/issues/detail?id=78

14
ответ дан ovgolovin 17 August 2018 в 08:40
поделиться
  • 1
    Нет ... нет еще одной итерации «нерегулярных регулярных выражений» Perl ». – ivan_pozdeev 30 May 2016 в 14:58
23
ответ дан phooji 17 August 2018 в 08:40
поделиться

Сбалансированные пары (например, круглые скобки) являются примером языка, который не может быть распознан регулярными выражениями.

Далее следует краткое объяснение математики, почему это так.

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

Например, состояние может использоваться для подсчета, скажем, несогласованных левых скобок. Но поскольку количество состояний для такого подсчета должно быть полностью ограничено, то данный FSM может рассчитывать до максимума n -1, где n - это число указывает, что FSM может быть в. Если n , скажем, 10, то максимальное количество несогласованных левых скобок FSM может совпадать, равно 10, пока оно не сломается. Поскольку вполне возможно иметь еще одну левую скобку, нет возможности FSM, который может правильно распознать полный язык совпадающих круглых скобок.

Ну и что? Предположим, вы просто выбрали действительно большой n ? Проблема в том, что в качестве способа описания FSM регулярные выражения в основном описывают все переходы из одного состояния в другое. Так как для любого N для FSM потребуется 2 перехода состояния (одно для сопоставления левой скобки и одно для правильного совпадения), само регулярное выражение должно расти, по крайней мере, с постоянным множителем, кратным n

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

expression ::= `(` expression `)` expression
           |    nothing
 
1
ответ дан SingleNegationElimination 17 August 2018 в 08:40
поделиться
  • 1
    Вы правы, но также и неправильны;) Современные языки программирования включают средства регулярных выражений, которые могут соответствовать таким вещам, как L = { ww | w \in {0,1}* }, который не является ни регулярным, ни контекстным. Верно, что они не могут соответствовать произвольно вложенным совпадающим скобкам, но не по той причине, о которой вы говорили. – phooji 28 March 2011 в 05:15
  • 2
    Исторически регулярные выражения начинались как средство выражения FSM, но с течением времени регулярные выражения получили большую силу, так что выразительная сила большинства современных регулярных выражений выходит за рамки обычной грамматики. Поэтому дискуссии о FSM необязательно относятся к регулярным выражениям. – sawa 28 March 2011 в 05:17
  • 3
    Мы говорим в разных целях. См. montreal.pm.org/tech/neil_kandalgaonkar.shtml для примера того, о чем я говорю. – phooji 28 March 2011 в 05:58
  • 4

Из связанного ответа:

Из утилиты LilyPond convert-ly (и написана / защищена авторским правом, поэтому я могу показать ее здесь):

def paren_matcher (n):
    # poor man's matched paren scanning, gives up
    # after n+1 levels.  Matches any string with balanced
    # parens inside; add the outer parens yourself if needed.
    # Nongreedy.
    return r"[^()]*?(?:\("*n+r"[^()]*?"+r"\)[^()]*?)*?"*n

convert -ly имеет тенденцию использовать это как paren_matcher (25) в своих регулярных выражениях, которые, вероятно, будут излишними для большинства приложений. Но затем он использует его для сопоставления выражений Схемы.

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

3
ответ дан user3489112 17 August 2018 в 08:40
поделиться
Другие вопросы по тегам:

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