2011-12-21 2 views
1

Я писал парсер файлов и в синтаксическом анализаторе Я анализирую каждую строку, используя регулярное выражение, если оно соответствует, тогда я разбираю данные.Соответствие шаблону n раз с использованием regex

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

Так у меня есть строка, которая выглядит следующим образом:

значение
(-3456 -3104 344 -24 -10 1 0 0) (-3456 -2976 344 -23 -10 1 0 0) (-3456 -2976 312 -23 -9 1 0 0) 

8 с плавающей точкой (выше кронштейны, повторяется п раз (3 выше, но может мне больше или меньше)

Я попытался это:.

\((.*?) \) 

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

/* iap 0 */ 4 5 1 (176 -1272 120) (176 -1272 264) (176 -1416 264) (176 -1416 120) 

Что я не хочу, чтобы это. Я думаю, это потому, что я не указываю начало ^

Но если я делаю, я, кажется, только для того чтобы получить 1-й набор скобок ...

^\((.*?) \) 

Я смотрел на это в течение нескольких часов , в кругах, но изо всех сил пытаюсь найти то, что мне нужно - указатели/помощь, пожалуйста?

ответ

1

Это будет делать трюк, чтобы отличить ваш пример:

^(\([0-9. -]+\) *)+$ 

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

+0

Это только кажется, чтобы захватить средний набор скобки для меня? В итоге я получаю 2 группы - 1 для всех и 1 для среднего набора. –

+0

Мне удалось копать глубже, и это работает, если я правильно иду по матчам/группам/захватам. Я отметил ответ Ахмада как полезный из-за объема четкой информации! –

2

Если вы хотите ограничить образец сравниваться восемь цифр попробовать следующую картину:

string pattern = @"\(\s*(-?\d+(?:\.\d+)?\b\s*){8}\)"; 

foreach (Match m in Regex.Matches(input, pattern)) 
{ 
    Console.WriteLine(m.Value); 
} 

Вы можете получить доступ к захваченным значениям в группе, а не использовать второе регулярное выражение, чтобы захватить числа. Это будет выглядеть следующим образом:

foreach (Match m in Regex.Matches(input, pattern)) 
{ 
    Console.WriteLine("Match: " + m.Value); 
    foreach (Group g in m.Groups) 
    { 
     foreach (Capture c in g.Captures) 
     { 
      Console.WriteLine(c.Value); 
     } 
    } 
    Console.WriteLine(); 
} 

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

Структура шаблона:

  • \(\s*: буквальный ( и пробельная (любое число повторений)
  • -?\d+(?:\.\d+)?: дополнительный отрицательный символ, один или несколько числа, и необязательная десятичная точка с последующим числами (последняя часть находится в группе, не участвующей в сборе, так как она находится в пределах (?: ...)
  • \b\s*: граница слова для обеспечения совпадения концов после каждой цифры, за которой следуют ноль или более пробельных символов
  • последние две части узора в улавливающей группы, так как они заключены в скобки
  • {8}: неоднократных ровно 8 раз
  • \): буквальное )
+0

К сожалению, у этой проблемы есть такая же проблема, как у меня - второй пример соответствует, если у этого есть набор скобок с 8 номерами, в то время как он не должен делать (у него есть часть шаблона, но он не следует только за шаблоном). –

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