Long Regex - Как бы вы это сделали? - PullRequest
1 голос
/ 01 августа 2009

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

Regex:

^([a-zA-Z0-9# ]+)-([a-zA-Z ]*)([a-zA-Z0-9_ ]+)-([a-zA-Z0-9_ ]+)-([a-zA-Z0-9_ ]+)-([a-zA-Z0-9_ ]+)-([a-zA-Z0-9_ ]+)-([a-zA-Z0-9_ ]+)-([a-zA-Z0-9_ ]+)-([a-zA-Z0-9_ ]+)-([a-zA-Z0-9_ ]+)-([a-zA-Z ~]+)([a-zA-Z0-9_ ]+)\.rpt$

Тесты:

TESTFIX - ABCD 10118 - E008 - E009 - IXX - IXX - IXX - IXX - IXX - IXX - SX ~ 91.rpt
TESTFIX - EFGD 10118 - E008 - E009 - IXX - IXX - IXX - IXX - IXX - IXX - SX ~ 92.rpt
TESTFIX - 10118_14041 M - E008 - E009 - IXX - IXX - IXX - IXX - IXX - IXX - SX ~ 93.rpt
TESTFIX - ABCD 10118 - E008 - E009 - IXX - IXX - IXX - IXX - IXX - IXX - SX ~ 93.rpt
TESTFIX - EFGD 10118 - E008 - E009 - IXX - IXX - IXX - IXX - IXX - IXX - SX ~ 93.rpt
TESTFIX - EFGD 10118 - E008 - E009 - IXX - IXX - IXX - IXX - IXX - IXX - SX ~ 93.rpt
TESTFIX - ABCD 10118 - E008 - E009 - IXX - IXX - IXX - IXX - IXX - IXX - SX ~ 93.rpt
#1REALLYLONGNAME - 10244 - E011 - E009 - IXX - IXX - IXX - IXX - IXX - IXX - DX ~ ALPHALTR.rpt
#1 LIVEREP - 10045 - E011 - E009 - IXX - IXX - IXX - IXX - IXX - IXX - SX ~ SING.rpt
#2 LIVEREP - 10045 M - E011 - E009 - IXX - IXX - IXX - IXX - IXX - IXX - SX ~ MUL.rpt
WELLREP - WELL10000 - E011 - E009 - IXX - IXX - IXX - IXX - IXX - IXX - SX ~ CLT.rpt

каждый раздел разделен последовательностью символов «-». Все разделы могут содержать пробелы и любой допустимый символ имени файла

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

Ответы [ 3 ]

5 голосов
/ 01 августа 2009

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

Вот очищенная версия:

^[\w# ]+ - [a-zA-Z ]*(?:[\w_ ]+ - ){9}[a-zA-Z]+ ~[\w_ ]+\.rpt$

Изменения включают в себя:

  • Удалены группы захвата "()" - Я предполагаю, что вы только проверка текста, так как вы этого не сделали упомянуть любой захват. Если тебе надо их достаточно легко добавить обратно
  • Использование класса буквенно-цифровых символов - "\ w", который эквивалентен "[a-zA-Z0-9]"
  • Заменили повторяющуюся часть посередине на «(?: [\ W_] + -) {9}». Это соответствует ([буквенно-цифровое подчеркивание] + -) девять раз. Это не захватывает из-за "?:", Который я поставил после первой круглой скобки.

EDIT:

Вот с задними группами захвата:

^([\w# ]+) - ([a-zA-Z ]*)(?:([\w_ ]+) - ){9}([a-zA-Z]+) ~ ([\w_ ]+)\.rpt$

Обратите внимание, что при прохождении пронумерованных групп захвата в третьей будет 9 захватов.

4 голосов
/ 01 августа 2009

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

Тем не менее, вот очищенная версия, которая выдает точно тот же результат, что и исходное выражение:

^([a-zA-Z0-9# ]+)-([a-zA-Z ]*)(?:([\w ]+)-){9}([a-zA-Z ~]+)([\w ]+)\.rpt$

Некоторые примечания о том, почему это отличается от других опубликованных ответов:

  • Согласно моей ссылке на Perl-совместимые регулярные выражения, \ w на самом деле также включает подчеркивание. ( Редактировать: это, очевидно, отличается от C #, что объясняется в ссылке на MSDN. Это различие может быть полезно отметить.)
  • Мое выражение предполагает, что у вас были пробелы в классах символов специально. Если на самом деле между черточками может быть несколько пробелов, оставьте это так, в противном случае переходите к другому ответу.
3 голосов
/ 01 августа 2009

Вы можете заменить каждый экземпляр a-zA-Z0-9_ на \ w. Кроме того, 0-9 можно немного сократить до \ d.

Вот классы символов, поддерживаемые C #: http://msdn.microsoft.com/en-us/library/20bw873z%28VS.71%29.aspx

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

^([a-zA-Z\d# ]+)-([a-zA-Z ]*)(?:([\w ]+)-){9}([a-zA-Z ~]+)([\w ]+)\.rpt$

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