Соответствующие раунды - PullRequest
1 голос
/ 26 декабря 2008

У меня есть текст со следующей структурой:

Round 1

some multiline text ...

Round 2

some multiline text ...

...

Round N

some multiline text ...

Я бы хотел сопоставить раунды с их многострочным текстом.

Ни одно из выражений не дает правильного результата:

(Round \ S \ d +) ((?! Round). *?)

(Round \ S \ D +) (. *?)

Может ли кто-нибудь мне помочь?

Заранее спасибо.

Ответы [ 6 ]

1 голос
/ 26 декабря 2008

Это вопрос C #?

(Round \ S \ d +) (. *?)

Использовать RegexOptions.Singleline

Singleline Указывает однострочный режим. Изменяет значение точки (.), Чтобы она соответствовала каждому символу (вместо каждого символа, кроме \ n).

И вам, вероятно, следует использовать Матчи вместо Матча.

1 голос
/ 26 декабря 2008

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

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

1 голос
/ 26 декабря 2008

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

/(Round\s\d+)(.*?)(Round\s\d+|$)/s

(Не уверен на 100%, сработает ли это регулярное выражение, я просто покажу вам, как использовать модификатор s.)

Редактировать: Протестировано на regexpal.com и похоже, что оно работает.

0 голосов
/ 26 декабря 2008

Алан, отличные советы для регулярных выражений. Мне было недостаточно практики с предвкушением.

/ (Round \ s + \ d +) (. *?) (? = Round \ s + \ d + | $) / s делает именно то, что мне нужно.

/ (Round \ s + \ d +) ((?! Round).) * / S также работает, но каждая буква должна быть отдельной записью.

Большое спасибо.

Чтобы описать мои данные более точно, вы можете посмотреть здесь, например: http://www.rsssf.com/tablesi/ital09.html

На самом деле мне нужно импортировать в свою базу данных всю информацию о раундах, матчах, результатах, их датах.

Мне нужно решить еще одну проблему: как соотнести мои уже сохраненные команды с теми, которые находятся в результатах матчей. Например, у меня есть команда «Интер» в моем БД. Но результат матча может выглядеть как

Интернационал 1-1 Ювентус или ФК Интер 1-1 Ювентус

В будущем я бы хотел, чтобы запросы регулярных выражений были чем-то вроде «получить все результаты матчей для Inter», чтобы не просматривать весь контент.

Поэтому моя идея заключалась в том, чтобы хранить с каждой командой их возможные имена (теги), а затем объединять их через |.

Например / (Интер | Интернационал | ФК Интер) \ s + \ d + - \ d + \ d + (\ w +) / s

Также у меня есть сомнения относительно (\ w +) для любого командного матча. Я боюсь, что мне нужно объединить все теги имен команд с | и использовать там. Для 30 команд и 2-3 тегов это будет огромное регулярное выражение.

Я ценю вашу помощь.

0 голосов
/ 26 декабря 2008

Это будет сделано с RegexOptions.SingleLine set:

Round\s+\d+(.*?)(?=Round\s\d|$)
0 голосов
/ 26 декабря 2008

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

/(Round\s+\d+)(.*?)/s

... первое, что делает часть (.*?), это пытается найти ноль символов. Это совершенно законное совпадение, и поскольку квантификатор неохотно, он тут же останавливается. Если вы собираетесь сделать это таким образом, после (.*?) должно быть что-то вроде этого:

/(Round\s+\d+)(.*?)(Round\s+\d+)/s

Таким образом, (.*?) не может останавливаться на нулевых символах; он должен сохранять совпадающие символы потребления, пока не достигнет места, где следующая часть регулярного выражения - (Round\s+\d+) - может вступить во владение. Но вы не хотите использовать это регулярное выражение, потому что оно потребляет часть того, что должно быть в следующем матче. Придерживаясь этого формата, вы можете использовать заглядывание в качестве конечного условия:

/(Round\s+\d+)(.*?)(?=Round\s+\d+|$)/s

Теперь он вынужден соответствовать целой записи, но позиция совпадения остается в начале следующей записи, поэтому следующая попытка совпадения начинается там. (РЕДАКТИРОВАТЬ: добавлен |$ к предпросмотру, чтобы соответствовать последней записи.)

РЕДАКТИРОВАТЬ: Я хотел прокомментировать и другое ваше регулярное выражение:

/(Round\s+\d+)((?!Round).*?)/s

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

/(Round\s+\d+)((?:(?!Round).)*)/s

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...