2015-08-02 3 views
3

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

Возьмите содержимое файлов следующий отчет (Примечание: # 2 отсутствует в "val2" часть.):

  • Файл № 1: "-val1 испытаний val2-result- val3-done- "
    • Ожидаемый результат:
      • Val1 Группа: тест
      • Val2 Группа: результат
      • val3 Группа: сделано
  • Файл № 2: "-val1 испытаний val3-done-"
    • Ожидаемый результат:
      • Val1 Группа: тест
      • Val2 Группа: (пусто)
      • val3 Группа: сделано

Я попытался следующие строки регулярных выражений:

Regex #1(Normal): "-val1-(?<val1>.+?)-val2-(?<val2>.+?)-val3-(?<val3>.+?)-" 

Задача: Файл # 1 работает нормально, но в файле # 2 регулярное выражение не соответствует, поэтому у меня нет никаких значений группы.

Regex #2(Non greedy)): "-val1-(?<val1>.+?)(-val2-(?<val2>.+?))?-val3-(?<val3>.+?)-" 
Regex #3(Boolean OR): "-val1-(?<val1>.+?)(-val2-(?<val2>.+?)|(.*?))-val3-(?<val3>.+?)-" 
Regex #4(Conditionnal): "-val1-(?<val1>.+?)(?(-val2-(?<val2>.+?))|(.+?))-val3-(?<val3>.+?)-" 
Regex #5(Conditionnal): "-val1-(?<val1>.+?)(?(-val2-(?<val2>.+?))(-val2-(?<val2>.+?)))-val3-(?<val3>.+?)-" 
Regex #6(Conditionnal): "-val1-(?<val1>.+?)(?(-val2-(?<val2>.+?))(-val2-(?<val2>.+?))|(.+?))-val3-(?<val3>.+?)-" 

Проблема: Файл № 2 работает как и ожидалось, но val2 группа файл # 1 всегда пусто.

Заключение: Поведение, по-видимому, состоит в том, что, даже если имеется необязательная группа, регулярное выражение будет устанавливать приоритет для пустого значения группы по текущему значению. Есть ли способ заставить получить значение дополнительных групп, когда они присутствуют, и только возвращать (пусто), когда они нет?

Примечание: Я использую последнюю платформу .NET, и код будет перенесен на Java (Android). Я стараюсь избегать использования нескольких операций для проблем с производительностью и пропускной способностью.

Любой может мне помочь?

+0

Как вы думаете, что делает третье значение необязательно является также действительным подходом для вас? Посмотрите на ['-val1- (? . +?) (- val2- (? . +?))? (- val3- (? . +?))? -'] (http: // regexstorm.net/tester?p=-val1-(%3f%3cval1%3e.%2b%3f)(-val2-(%3f%3cval2%3e.%2b%3f))%3f(-val3-(% 3f% 3cval3% 3e.% 2b% 3f))% 3f- & я = -val1-тест-знач2-результат-val3-done-% 0d% 0a-знач1 тест-val3-done- & о = п). –

+0

в C#, в тестовой программе, которую я запускал, Regex # 5 работает как для file1, так и для file2. Разве это не то, что вы получаете? – gymbrall

+0

Оказывается, мой упрощенный пример недостаточно реалистичен. Вот лучший (основанный на извлечении содержимого html): https://regex101.com/r/jY4jK1/2; Я установил, что 3 последних группы являются факультативными, и результат состоит в том, что они не извлекаются, и любая идея о том, как заставить его работать? –

ответ

1

Это возможно, если сделать некоторые предположения:

  1. значение может отсутствовать, но они всегда находятся в том же порядке
  2. первого значение всегда присутствует
  3. есть разделитель перед и после того, как стороны мы ищем

 

-val1-([^-]+)(?:-val2-([^-]+)|)(?:-val3-([^-]+)|)- 

https://regex101.com/r/yY6vF9/1

+0

Hum ... ну, мой пример был слишком упрощенным ... Не могли бы вы взглянуть на это? https://regex101.com/r/mI5uI0/1. Первые две группы будут всегда присутствовать, все группы будут в том же порядке, и, как вы можете видеть, есть какой-то html-код, который можно использовать в качестве разделителей. Теперь проблема заключается в том, что если группа «Time1» отсутствует (в примере я добавил «notpresent»), все регулярное выражение больше не подходит. Не могли бы вы показать мне, как адаптировать ваше решение к этой ситуации? –

+0

Это тот же принцип https://regex101.com/r/mI5uI0/2, хотя это регулярное выражение не 100% -ное сохранение, синтаксический анализатор html будет лучше. Здесь time1 и time2 являются необязательными и порядок должен быть сохранен. – maraca

+0

Thanx. Я думаю, что могу использовать Html Parsing (используя XPaths); Я надеюсь, что не будет большого снижения производительности, так как я буду извлекать информацию один за другим в одной исходной строке. :-) –

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