Пазл Регулярное выражение - PullRequest
0 голосов
/ 02 декабря 2008

In (Visual Basic, .NET):

  Dim result As Match = Regex.Match(aStr, aMatchStr)
  If result.Success Then
      Dim result0 As String = result.Groups(0).Value
      Dim result1 As String = result.Groups(1).Value
  End If

С: aStr равно (пробел - это нормальный пробел, и между n и () есть семь пробелов:

"AMEVDIEERPK + 7 Oxidation       (M)"

Почему result1 становится пустой строкой для aMatchStr, равной

"\s*(\d*).*?Oxidation\s+\(M\)"

но становится "7" для aMatchStr, равным

"\s*(\d*)\s*Oxidation\s+\(M\)"

(result0 становится равным "AMEVDIEERPK + 7 Окисление (M)")

(Это от MSQuant , MascotResultParser.vb , функция modificationParseMatch()).

Ответы [ 8 ]

4 голосов
/ 02 декабря 2008

\ s * Ноль или более пробелов

(\ d *) Ноль или более цифр (захвачено)

. *? Любые символы (не жадные, поэтому до следующего соответствия

Окисление Соответствует слову Окисление

\ s + (M) Соответствует одному или нескольким пробелам, затем (M)

Проблема здесь в том, что вы соответствуете 0 или более любых символов перед словом Oxidation, включая любые возможные цифры, съедая цифры, которые могут соответствовать предыдущему \ d

\ S * (\ д *) \ S * Окисление \ S + (М)

Разница здесь в том, что вы указываете пробел только перед Окислением. Не ест цифры.

Измените \ d * на \ d +, чтобы поймать числа

3 голосов
/ 02 декабря 2008

Я думаю, это потому, что сопоставление начинается с первого символа и продолжается оттуда ...

Для вашего первого регулярного выражения:

Does "AMEVDIEERPK + 7 Oxidation (M)" match "\s*(\d*).*?Oxidation\s+(M)"?  Yes.. stop matching.

Для вашего второго регулярного выражения:

Does "AMEVDIEERPK + 7 Oxidation (M)" match "\s*(\d*)\s*Oxidation\s+(M)"?  No...
Does "MEVDIEERPK + 7 Oxidation (M)" match "\s*(\d*)\s*Oxidation\s+(M)"?  No...
Does "EVDIEERPK + 7 Oxidation (M)" match "\s*(\d*)\s*Oxidation\s+(M)"?  No...
...
Does " 7 Oxidation (M)" match "\s*(\d*)\s*Oxidation\s+(M)"?  Yes

Если бы для первого регулярного выражения вы использовали \d+ вместо \d*, вы бы получили лучший результат.

Это не в точности , как работают регулярные выражения, но вы поняли.

1 голос
/ 02 декабря 2008

Прошу прощения, в синтаксисе есть что-то еще ...

На знак плюс нельзя положиться. Отделяет (пептидная) последовательность и (пептидные) модификации. Там может быть более одной модификации для каждой последовательности. Образец с двумя модификациями (между "2" и 7 пробелами "L"):

"KLIDLTQFPAFVTPMGK + Окисление (M); 2 Лизин-13C615N2 (K-full)"

Пользователь может указать "\ S + \ s + (K-full)" для второго модификация и "2" должны быть извлечены.

Вот еще несколько примеров строк (после знака плюс):

"Фосфо (ST); 2 Диметил (К); Диметил (N-член)"

"Фосфо (ST); 2 Диметил: 2Н (4) (К); Диметил: 2Н (4) (N-член)"

"N-Ацетил (Белок)"

"2 Диметил: 2H (4) (K); Диметил: 2H (4) (N-член)"

"N-ацетил (белок); 2 лизин-13C615N2 (полный K)"

«Окисление (М); N-Ацетил (Белок)»

«Окисление (М); N-ацетил (белок); Лизин-13C615N2 (К-полный)»

"N-ацетил (белок); лизин-13C615N2 (K-full)"

«Окисление (М); Лизин-13C615N2 (К-полный)»

"Окисление (М)"

"2 Окисление (М); Лизин-13C615N2 (К-полный)"

Образец файла с пользовательскими правилами можно найти по адресу (упаковано в 7-почтовый формат):

<<a href="http://pmortensen.eu/1/MSQuant/CEBIquantModes,2008-11-10.7z" rel="nofollow noreferrer">http://www.pil.sdu.dk/1/MSQuant/CEBIquantModes,2008-11-10.7z>

1 голос
/ 02 декабря 2008

Я остановился на использовании \w* на данный момент. Потребуется пользователь указать соответствие для любого белого пространства, но оно охватывает Большинство случаев для этого конкретного приложения и как это обычно используется.

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

\s*(\d*)\s*\w*Oxidation\s+\(M\)
1 голос
/ 02 декабря 2008

С обновлением синтаксиса нам не нужно беспокоиться о разнице между \ d + и \ d *. Всегда присутствует знак +, даже если нет цифр. Соответствие этому + ограничивает регулярное выражение до такой степени, что оно работает как ожидалось:

"\s*    // whitespace before +
 \+     // The + sign itself
 \s*    // whitespace after +
 (\d*)  // optional digits
 .*?    // any non-digit between the last digit and Oxidation (M)
 Oxidation\s+\(M\)"

Поскольку знак + должен совпадать первым и совпадать точно один раз, префикс AMEVDIEERPK не может быть сопоставлен.

1 голос
/ 02 декабря 2008

Чтобы ответить на ваше второе сообщение, вы (или ваш пользователь) можете указать \w*dation\s+\(M\), чтобы соответствовать оксидации (M), градации (M) или дации (M).

1 голос
/ 02 декабря 2008

Спасибо за быстрый ответ!

Числа на входе не учитываются, если есть только один (пептидная) модификация вместо 7, как в предыдущем например, например ::1003*

"AMEVDIEERPK + Окисление (M)"

и совпадения не будет, если используется "\ d +". Но может я следует использовать два регулярных выражения, по одному для каждого из этих двух случаев. Это увеличило бы сложность программы несколько (как я хочу, чтобы избежать мусора памяти от построение регулярного выражения для каждой строки соответствует), но приемлемо.

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

Прямо сейчас к правилу пользователя добавляется "\ s * (\ d *) \ s *" и пользователь должен, таким образом, указать «Окисление \ s + (M)» для матч. Например, указав "dation \ s + (M)" не будет работать.

1 голос
/ 02 декабря 2008

". *?" в этом примере всегда будут совпадать ноль символов, так как "*?" делает кратчайшее совпадение. В результате, поскольку перед символом O стоит пробел, "\ d *" может соответствовать 0 цифрам.

(Извините за пробелы в кавычках; автоформатер съел мой синтаксис.)

Ссылка: Квантификаторы в регулярных выражениях (MSDN)

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