Regex - захват повторной группы - PullRequest
1 голос
/ 12 мая 2011

Хорошо, я прочитал учебные пособия и поднял голову слишком сильно, чтобы я мог ясно видеть сейчас.

Я пытаюсь получить параметры и информацию о их типе из сигнатуры функции. Итак, с такой подписью:

function(/*string*/a,b,c)

Я хочу получить такие детали:

type: string
param:a
param:b
param:c

Это тоже нормально:

type: string
param:a
type: null (or whitespace)
param:b
type: null (or whitespace)
param:c

Итак, я придумал это регулярное выражение, которое делает общую ошибку повторения захвата (я включил явный захват):

function\(((\/\*(?<type>[a-zA-Z]+)\*\/)?(?<param>[0-9a-zA-Z_$]+),?)*\)

Проблема в том, что я не могу исправить ошибку. :(. Пожалуйста, помогите!

Ответы [ 3 ]

3 голосов
/ 12 мая 2011

Как правило, вам потребуется два шага, чтобы получить все данные.
Сначала сопоставьте / подтвердите всю функцию:

function\((?<parameters>((\/\*[a-zA-Z]+\*\/)?[0-9a-zA-Z_$]+,?)*)\)

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

. Если вы используете .Net, то, по любому случаю, вам повезло..Net хранит полную запись всех захватов каждой группы, поэтому вы можете использовать коллекцию:

match.Groups["param"].Captures

Некоторые примечания:

  • Если вы хотите захватить более одного типа, вам определенно нужны пустые совпадения , так что вы можете легко комбинировать совпадения (хотя вы можете сортировать, но захват 1-к-1 лучше).В этом случае вам понадобится дополнительная группа внутри вашей захваченной группы: (?<type>(\/\*[a-zA-Z]+\*\/)?)
  • Вам не нужно избегать косых черт в шаблонах .Net - / не имеет там особого значения(C # /. Net не имеет разделителей регулярных выражений).

Вот пример использования перехватов.Опять же, главное - поддерживать связь между type и param: вы хотите захватывать пустые типы, чтобы не терять счет.
Pattern:

function
\(
(?:
    (?:
        /\*(?<type>[a-zA-Z]+)\*/    # type within /* */
        |                           # or
        (?<type>)                   # capture an empty type.
    )
    (?<param>
        [0-9a-zA-Z_$]+
    )
    (?:,|(?=\s*\)))     # mandatory comma, unless before the last ')'
)*
\)

Код:

Match match = Regex.Match(s, pattern, RegexOptions.IgnorePatternWhitespace);
CaptureCollection types = match.Groups["type"].Captures;
CaptureCollection parameters = match.Groups["param"].Captures;
for (int i = 0; i < parameters.Count; i++)
{
    string parameter = parameters[i].Value;
    string type = types[i].Value;
    if (String.IsNullOrEmpty(type))
        type = "NO TYPE";
    Console.WriteLine("Parameter: {0}, Type: {1}", parameter, type);
}
1 голос
/ 21 августа 2011

Прошло много времени с тех пор, как этот вопрос был активным, но, думаю, я наконец-то нашел ответ.

Я думаю, что искал ту же ситуацию, что и вы, но для использования с PHP, и естьответ в другом посте я нашел, что работает очень хорошо, используя команды \K и \G из PCRE.См. Ответ Алана Мура здесь: Регулярное выражение PHP - повторяющееся совпадение группы

Моя проблема пыталась извлечь все значения ячеек в таблице, где каждая строка содержала 6-значное число, 20x однозначное или двузначное число и несвязанное однозначное или двузначное число.Решение было:

<tr class="[^"]*">\s+<td>(\d{6})<\/td>|\G<\/td>[^<>]*+<td>\K\d{1,6}|<td>(\d{1,2})<\/td>

Очень хорошее решение, если я сам так скажу!

1 голос
/ 12 мая 2011

страница, на которую вы ссылались, упоминается с помощью ?: для не захвата, а затем окружает повторяющийся захват в своей собственной группе.Я предполагаю, что они предлагают что-то вроде этого function\(((?:(\/\*(?<type>[a-zA-Z]+)\*\/)?(?<param>[0-9a-zA-Z_$]+),?)*)\)

Мне нравится использовать http://gskinner.com/RegExr/ для проверки моих выражений, но он не будет показывать повторные захваты.Возможно, вам придется циклически просматривать результаты в любой возвращаемой структуре, чтобы увидеть значения в других языках, отличных от .NET.

извините, я не смог более тщательно протестировать ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...