Регулярное выражение для аргументов функции разбора с функциями

regex

670 просмотра

2 ответа

1481 Репутация автора

Я хочу получить аргументы функции строки.

sample( 5*5 ) euros

Это работает правильно с:

([^\s\)]+)\(([^\)]+)\)

Демо здесь .

Проблема в том, что я помещаю другую функцию в аргумент:

sample( decimal( 5*5 ) ) euros

Только с функцией это работает с:

([^\s\)]+)\((.+)\)

Демо здесь .

Но с двумя или более функциями я не могу получить аргументы функции:

sample( decimal( 5*5 ) ) toString(euros)

Как я могу получить аргументы функции с помощью регулярного выражения?

Автор: SnakeDrak Источник Размещён: 18.07.2016 06:41

Ответы (2)


1 плюс

316549 Репутация автора

Используйте взгляд в будущее, в котором указан следующий символ скобки (если он есть) - открытый , и используйте квантификатор неохотно.

Это должно работать:

([^\s\)]+)\((.+?)\)(?=[^()]*(\(|$))
Автор: Bohemian Размещён: 18.07.2016 06:48

1 плюс

367408 Репутация автора

Решение

Если вы пишете парсер, вы можете обойтись без регулярных выражений. С образовательной точки зрения в PHP PCRE regex вы можете использовать рекурсию и вызовы подпрограмм .

Посмотри на

(?<name>[^\s()]+)(\((?<body>(?>[^()]++|(?2))*)\))

Посмотреть демо-версию регулярного выражения

Группа «name» будет содержать имя функции, а группа «body» будет содержать то, что находится внутри соответствующих скобок.

Обратите внимание, что вам нужно добавить оба (и )в класс отрицанных символов, (?<funcion>[^\s()]+) потому что в случае, если у вас есть sample(decimal(3*3))эта группа, захватит подстроку до )( sample(decimal). Таким образом, вам нужно исключить оба (и ).

Эта (\((?<body>(?>[^()]++|(?2))*)\))часть представляет собой группу захвата (с ID = 2 ), которая может быть повторена (то есть «повторена», «расширена» много раз) с помощью вызова подпрограммы (?2).

Это соответствует

  • \( - открытая круглая скобка
  • (?<body>(?>[^()]++|(?2))*) - Группа «тело», которая соответствует нулю или более последовательностей:
    • [^()]++- 1+ , кроме символов (и )или
    • (?2)- весь \((?<body>(?>[^()]++|(?2))*)\)подшаблон
  • \) - закрывающая скобка

Необходимость (?2) вызова подпрограммы (по сравнению с рекурсией с (?R)) продиктована тем фактом, что нам нужно повторить / повторить часть шаблона.

Поскольку Группа 2 является «технической» группой захвата, было бы неплохо использовать именованные группы захвата для тех частей, которые мы действительно хотим использовать.

Автор: Wiktor Stribiżew Размещён: 18.07.2016 06:50
Вопросы из категории :
32x32