2014-06-11 2 views
1

Я хотел бы извлечь первый и второй параметры функции (если они есть).Как извлечь параметры в сложные строки

Например, от __('param1', 'param2'), я хотел бы извлечь param1 и param2.

Вот что я нахожу сложным:

  1. Там не может быть вторым параметром
  2. Котировки параметров могут быть простыми или двойными кавычками
  3. в двойных кавычках, параметр может содержать апостроф, и наоборот.

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

__('My test') 
__('Uber test', 'dan') 
__("test t'fdgfgd") 
__("test t'dfgdgf","fgf', 'dgfdg") 

Вот what I have tried.

+0

Синтаксических языки программирования с регулярными выражениями является безнадежным предприятием в большинстве случаев. Рассмотрим правильный парсер (например, https://github.com/nikic/PHP-Parser). – georg

ответ

1

Вы правы, это немного сложнее, но это работает (см demo со всеми вашими примерами):

(?:__\(|\G['"]\s*,\s*)(['"])\K.*?(?=(?<!\\)\1) 

@NiettheDarkAbsol упомянул о возможности кавычек экранированы, поэтому я добавил условие для сложных строк таких as:

__('My \'test') 
__("My \"test") 

Как это работает?

Это немного долго знамением-на-токенов объяснения, но ...

  1. Эта часть (?:__\(|\G['"]\s*,\s*)(['"])\K позиции нас внутри открытия цитаты, оставив то, что уже было подкреплено до сих пор благодаря «Dr . \K eep out ". Вернемся к этому позже.
  2. В .*? лениво матчи символы до ...
  3. точки, где опережения (?=(?<!\\)\1) можно утверждать, что далее следует такой же характер, как открытие цитаты (\1 обратной ссылки), пока он не предшествует избегая обратной косой черты ((?<!\\))
  4. Хорошо, как часть 1 работала? Перед «Доктор \K ВЕПА из» мы либо матча открытия __\( затем строки открытия, захваченного (['"]), чтобы убедиться, что строка закрытия идентична (\1 ссылки ниже) ... или ...
  5. утверждая, с \G, который мы позиционируем после последнего символа предыдущего матча, ['"]\s*,\s* соответствует его закрывающей котировке, затем запятой (в окружении дополнительных пробелов), затем вводной строкой, снятой (['"]), чтобы убедиться, что замыкающая строка идентична (\1 ссылка позже).

И все, что есть!

+0

Как этот дескриптор скрывает кавычки? –

+0

@NiettheDarkAbsol Вы правы, хотя это не в спецификации, это важный случай, чтобы принять во внимание. Готово. Спасибо! :) – zx81

0

Вот один регулярное выражение, которое дало бы вам матчи:

(?:(?:')((?:(?!(?<!\\)').)+)(?:'(?:,\s*)?))|(?:(?:")((?:(?!(?<!\\)").)+)(?:"(?:,\s*)?)) 

Demo

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