Мое регулярное выражение слишком много соответствует.Как мне остановить это?

StackOverflow https://stackoverflow.com/questions/22444

  •  09-06-2019
  •  | 
  •  

Вопрос

J0000000: Transaction A0001401 started on 8/22/2008 9:49:29 AM
J0000010: Project name: E:\foo.pf
J0000011: Job name: MBiek Direct Mail Test
J0000020: Document 1 - Completed successfully

У меня есть эта гигантская уродливая строка, и я пытаюсь извлечь из нее фрагменты с помощью регулярного выражения.

В этом случае я хочу захватить все после «Имя проекта» до той части, где написано «J0000011:» (каждый раз 11 будет другим числом).

Вот регулярное выражение, с которым я играл

Project name:\s+(.*)\s+J[0-9]{7}:

Проблема в том, что он не останавливается, пока не достигнет цели. J0000020: в конце.

Как заставить регулярное выражение останавливаться при первом появлении Дж[0-9]{7}?

Это было полезно?

Решение

Делать .* не жадный, добавив '?' после этого:

Project name:\s+(.*?)\s+J[0-9]{7}:

Другие советы

Использование нежадных кванторов здесь, вероятно, является лучшим решением, еще и потому, что оно более эффективно, чем жадная альтернатива:Жадные совпадения обычно заходят настолько далеко, насколько это возможно (здесь, до конца текста!), а затем отслеживают символ за символом, чтобы попытаться сопоставить следующую часть.

Однако вместо этого рассмотрите возможность использования класса отрицательных символов:

Project name:\s+(\S*)\s+J[0-9]{7}:

\S означает «все, кроме пробелов, и это именно то, что вам нужно».

Хорошо, ".*" это жадный селектор.Вы делаете это не жадным, используя ".*?" При использовании последней конструкции механизм регулярных выражений на каждом этапе сопоставляет текст с "." попытаться сопоставить все, что происходит после ".*?".Это означает, что если, например, после ".*?", то оно ничему не соответствует.

Вот что я использовал. s содержит исходную строку.Этот код специфичен для .NET, но большинство разновидностей регулярных выражений будут иметь что-то похожее.

string m = Regex.Match(s, @"Project name: (?<name>.*?) J\d+").Groups["name"].Value;

Я бы также рекомендовал вам поэкспериментировать с регулярными выражениями с помощью «Expresso» — это отличная (и бесплатная) утилита для редактирования и тестирования регулярных выражений.

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

Например, при создании регулярного выражения с помощью пользовательского интерфейса и выборе «*» у вас есть возможность установить флажок «Как можно меньше» и увидеть полученное регулярное выражение, а также протестировать его поведение, даже если вы не знакомы с не жадные выражения раньше.

Доступно для скачивания на их сайте:http://www.ultrapico.com/Expresso.htm

Экспресс-загрузка:http://www.ultrapico.com/ExpressoDownload.htm

(Название проекта:\s+[A-Z]:(?:\\w+)+.[a-zA-Z]+\s+J[0-9]{7})(?=:)

Это подойдет вам.

Добавление (?:\\w+)+.[a-zA-Z]+ будет более ограничительным вместо .*

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top