2015-05-28 5 views
1

Я пытаюсь написать регулярное выражение, которое будет использоваться в PHP, чтобы соответствовать аргументам определенной функции. Вот пример такого рода вещи, которые я пытаюсь соответствовать:Regex для сопоставления аргумента функции

$content = "myfunction('Text with (nested) parentheses') 
      myfunction('Text2 without nested parentheses') 
      myfunction('Text2 with variables ' + myvar) 
      myfunction(myvar) 
      myfunction(myvar1 + \"(nested) some text here\" + (error.length ? \" \" + errorMsg : \"\"))"; 

preg_match_all('/myfunction\(([^()]|(?R))*\)/', $content, $matches); 

Как вы можете себе представить, все возвращается, за исключением одного с вложенными скобками. The | (? R) - это то, что я ожидаю, это заставило бы его работать. Если я делаю это, однако, все работает, как ожидалось:

$content = "('Text with (nested) parentheses') 
     ('Text2 without nested parentheses') 
     ('Text2 with variables ' + myvar) 
     (myvar)"; 

preg_match_all('/\(([^()]|(?R))*\)/', $content, $matches); 

К сожалению, мне нужно иметь имя функции, потому что я только хочу, чтобы соответствовать одной конкретной функции. Это возможно с регулярным выражением?

ответ

3

Используйте взгляд вперед, чтобы исключить соответствующие на близких скобок, когда в кавычки:

myfunction\((.*?)\)(?=(([^'"]*['"]){2})*[^'"]*$) 

См live demo.

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

Коэффициент неохотного *? остановится на в начале такой матч, если у вас есть несколько совпадений на этой же линии.

+0

гораздо более элегантный, чем то, что я собирался предложить. Я могу подтвердить, что это работает [link] (https://regex101.com/r/iF0gN7/3) – pcnate

+0

Это почти работает. Добавлен один вышеприведенный случай, который он не может получить. Я изменил ваше регулярное выражение на это: /myfunction\((.*?)\)(?=(([^'"]*['"]){2})*[^'"]*$)/ и это еще ближе, единственное, что он не забирает, это последнее), которое следует за «» в самом конце нового тестового примера, который я представил. Очень близко, и я, вероятно, могу жить с ним, если он не может быть включенным – Rocket04

+0

О, и, кстати, большое спасибо за это, даже если я не смогу добиться его совершенства, он будет достаточно полезен в его текущей форме. – Rocket04

Смежные вопросы