Сведения о вопросе

PIRLO

10:25, 13th August, 2020

Теги

regex    

Мой regex слишком сильно совпадает. Как мне заставить его остановиться?

Просмотров: 481   Ответов: 5

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

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

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

Вот тот regex, с которым я играл

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

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

Как заставить regex остановиться при первом появлении J[0-9]{7} ?



  Сведения об ответе

qwerty101

02:13, 1st August, 2020

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

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


  Сведения об ответе

прога

14:08, 28th August, 2020

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

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

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

\S означает " все, кроме whitespace, и это именно то, что вы хотите.


  Сведения об ответе

SILA

16:44, 25th August, 2020

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

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

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


  Сведения об ответе

ASSembler

15:57, 19th August, 2020

Я бы также рекомендовал вам поэкспериментировать с регулярными выражениями с помощью "Expresso"-это отличная (и бесплатная) утилита для редактирования и тестирования regex.

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

Например, при построении вашего regex с помощью UI и выборе " * " у вас есть возможность проверить checkbox "As few as possible" и увидеть результирующий regex, а также проверить его поведение, даже если вы раньше не были знакомы с нежадными выражениями.

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

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


  Сведения об ответе

SEEYOU

01:20, 23rd August, 2020

(Проект name:\s+[A-Z]:(?:\\Вт+)+.[a-zA-Z]+\s+J[0-9]{7}) (?=:)

Это будет работать на вас.

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться