Regexp находит положение разных символов в строке

У меня есть строка, соответствующая следующему шаблону:

(cc)-(nr).(nr)M(nr)(cc)whitespace(nr)

где cc – произвольное количество буквенных символов, nr – произвольное количество цифровых символов, а M – фактическая буква M.

Например:

ASF-1.15M437979CA 100000
EU-12.15M121515PO 1145

Мне нужно найти позиции -, . и M в строке. Проблема в том, что начальные и конечные символы также могут содержать букву M, но мне нужна только та, что посередине.

В качестве альтернативы было бы достаточно вычитания первых символов (до -) и первых двух чисел (как в (nr).(nr)M...).


person Freud    schedule 18.05.2015    source источник
comment
Поскольку (cc) и (nr) не могут содержать '-' или '.' почему бы вам не использовать IndexOf? После нахождения '.' Вы можете искать букву «М» в позиции после «.».   -  person Mehrzad Chehraz    schedule 18.05.2015
comment
Можете ли вы отредактировать свой вопрос и добавить решение, которое у вас есть? Спасибо!   -  person Luís Cruz    schedule 18.05.2015
comment
У меня есть решение, которое предлагает Мехрзад Чехраз. Но хочется красивого :-)   -  person Freud    schedule 18.05.2015
comment
Включите свое решение, и мы сделаем его лучше, если это необходимо.   -  person Mehrzad Chehraz    schedule 18.05.2015


Ответы (2)


Если вам нужно решение на основе регулярных выражений, вам просто нужно использовать 3 группы захвата вокруг необходимых шаблонов, а затем получить доступ к свойству Groups[n].Index:

var rxt = new Regex(@"\p{L}*(-)\d+(\.)\d+(M)\d+\p{L}*\s*\d+");
// Collect matches
var matches = rxt.Matches(@"ASF-1.15M437979CA 100000  or  EU-12.15M121515PO 1145");
// Now, we can get the indices
var posOfHyphen = matches.Cast<Match>().Select(p => p.Groups[1].Index);
var posOfDot = matches.Cast<Match>().Select(p => p.Groups[2].Index);
var posOfM = matches.Cast<Match>().Select(p => p.Groups[3].Index);

Выход:

posOfHyphen => [3, 32]
posOfDot    => [5, 35]
posOfM      => [8, 38]
person Wiktor Stribiżew    schedule 18.05.2015

Регулярное выражение:

string pattern = @"[A-Z]+(-)\d+(\.)\d+(M)\d+[A-Z]+";
string value = "ASF-1.15M437979CA 100000  or  EU-12.15M121515PO 1145";

var match = Regex.Match(value, pattern);

if (match.Success)
{
    int sep1 = match.Groups[1].Index;
    int sep2 = match.Groups[2].Index;
    int sep3 = match.Groups[3].Index;
}
person Stas BZ    schedule 18.05.2015
comment
Также совершенно хороший и действительный soultion. Спасибо - person Freud; 18.05.2015