Улучшите ваши навыки создания шаблонов регулярных выраженийИсточник: IBM developerWorks Россия Михаэль Штутц
ВведениеКаждый день UNIX-администраторы создают и используют регулярные выражения (regexps) чтобы сопоставлять образцы текста. Большинство языков поддерживает некоторую реализацию регулярных выражений. Некоторые приложения (типа EMACS) имеют возможности поиска регулярных выражений, регулярные выражения можно использовать с множеством инструментов командной строки. Для любого приложения ключ к созданию хороших регулярных выражений - это распознавание образца, который содержит только ту информацию, которую вам надо проверять, так, чтобы ничто другое от входных значений не мешало. Забегая вперед, скажу, что эта статья содержит несколько методов проектирования шаблонов регулярных выражений и описание того, как они могут быть полезны в различных распространенных ситуациях. Использование регулярных выражений (regexps)Замечу, что примеры в этой статье являются регулярными выражениями для Portable Operating System Interface-extended (POSIX-extended). Если вы используете их в командной строке (с утилитой Полное совпадениеВы знаете, что метасимвол Это хороший базовый шаблон для поиска в файле словаря пользователя (/usr/dict/words). Некоторые пользователи UNIX перемещают этот файл в /usr/share/dict/words. Например, скажем вы забыли как пишется слово fuchsia. В нем пишется sh или cs? Все, в чем вы уверены, это то, что оно начинается с fu и заканчивается ia. Попробуем поискать с помощью следующего шаблона:
Флаг Сопоставление строк, основанное на длинеИспользуйте метасимвол "фигурные скобки" ( Таблица 1.Значение фигурных скобок
Не все реализации расширенных регулярных выражений поддерживают фигурные скобки. В зависимости от реализации фигурные скобки могут потребовать экранирования обратной наклонной чертой (backslash) при использовании. Можно использовать это регулярное выражение для получения набора слов из словаря, упорядоченных по длине. Точное число слов, которое вы получите, зависит от числа слов в словарном файле системы. Результат будет примерно таким, как показано в примере 1. В этом примере самой распространненой длиной слова было девять букв, чему в словаре соответствует 32380 слов. Словарь не содержит слов, в которых 25 или более букв, и самое длинное слово содержит не 21 букву, это не disestablishmentarian , как вы могли бы подумать, потому что есть еще 81 слово такой же длины, например superincomprehensible и phoneticohieroglyphic . Приз за самое длинное слово в словаре UNIX поделен между пятью словами, включая pathologicopsychological . Пример 1. Подсчет слов с числом букв X в словаре
Сравнение словУгловые скобки
Угловые скобки могут сильно сэкономить время, но часто их недостаточно эффективно используют, возможно из-за того, что не каждая реализация регулярных выражений поддерживает их. Если реализация, которой пользуетесь вы, поддерживает, сделайте их использование привычкой. Поместим в угловые скобки слово, чтобы искать сопоставления только для него, например, так:
Регулярное выражение в этом примере не выберет слова ecosystem , systemic или system/70 , не сопоставит оно и строки, где образец Комбинируйте угловые скобки с круглыми, чтобы искать совпадения для частей слов. Для сравнения строк, содержащих слова, начинающиеся с pre , используйте:
Предшествующий пример подбирает строки, содержащие слова preface и preposterous , но не spread или Dupre . Сопоставление двойных словИспользуя угловые скобки, можно быстро найти двойные слова: после слова идет пробел и затем снова то же слово. Вы также можете использовать backreference , который сопоставляет часть образца самому себе и является рекурсивной возможностью большинства современных реализаций регулярных выражений. (Заключите часть образца, которую ыы хотите сделать эталонной, в круглые скобки и вызовите backreference с помощью бэкслэша ("\"), после этого запишите число вложений слова-образца: 1 для первой группы круглых скобок, 2 для второй группы круглых скобок и так далее.) Чтобы найти двойные слова, ищем слово, за которым следует любое число пробелов и снова точно такое же слово, которое определили с помощью обратной ссылки на первую группу круглых скобок:
Этот пример не находит двойные слова, отделенные друг от друга запятой, такие как It's been a long, long time . Для поиска всех двойных слов, включая те, что разделены пробелами и другими знаками препинания, используйте это:
Для того чтобы сопоставление не зависело от регистра символов, используйте флаг Сопоставление временДавайте перейдем к следующей ситуации, с которой вы постоянно сталкиваететсь: время и дата. Ниже представлена пара советов, как заставить регулярные выражения работать с корректными образцами времени и дат. Вы не можете просто искать двузначные числа, которые определяют минуты и секунды, потому что минуты и секунды отсчитываются от 0 до 59; для их сопоставления заключите в скобки подходящие диапазоны для десятков и единиц для каждой из двух колонок:
Без выражения отрицания в начале у последнего примера регулярное выражение будет находить время без двоеточия. Такое выражение, в зависимости от ваших входных данных, может иметь отношение к средневолновому радио (известное в Соединенных Штатах как AM-радио), например, 1450 AM. Сопоставление месяцевСопоставление 12 месяцев требует списка, разделенного вертикальной чертой - оператор
Заметьте, что для обоих примеров выше May (май) является исключением. Это единственный месяц, у которого полное название совпадает с трехбуквенным сокращением, поэтому правильно выполненное сравнение должно содержать любой из двух вариантов написания, для того чтобы слова типа Mayflower не вызвали ошибочного истинного значения. Примеры выше также могут оказаться непригодными к работе (путем возвращения ошибочного истинного значения), когда сравниваемому образцу предшествуют символы, отличные от пробела или начала строк. Едва ли это может случиться в художественном тексте, но может случиться, например, в исходном коде программы, где используется переменная с именем Для решения этих проблем, делайте следующее:
Но все еще осталась потенциальная ошибка: ни один из этих примеров не предназначен для поиска в английской прозе, потому что есть шанс, что они вернут ложное совпадение, со словами типа Janelle или Augury. Чтобы исправить это, следует заключить каждый месяц в оболочку для слова оболочку для слова (слово - подразумевается синтаксическая единица). Предыдущие примеры хорошо подходят для некоторых случаев без каких-либо дополнительных шагов для их модернизации. В других случаях эти образцы могут быть значительно упрощены: например, если вы осуществляете поиск в лог-файле, содержащем только числовые данные с датами, включающими в себя заглавные буквы, регулярное выражение типа Сопоставление датВы можете комбинировать сопоставления, как описано в таблице 1, для поиска дат. Для того чтобы сопоставить месяц, день, год, используйте следующее регулярное выражение (апостроф является служебным символом регулярного выражения, поэтому его следует брать в двойные кавычки):
Это регулярное выражение ищет соответствия для девяти различных форматов даты:
Неверные истинные значения, не соответствующие действительности, в данном регулярном выражении, вклюают Order 99, 99. Для того чтобы убрать их, можно соединить это регулярное выражение с выражением для месяцев, как описано выше, и в итоге регулярное выражение будет находить только настоящие названия месяцев.Также измените числовые диапазоны, чтобы избежать ложных сопоставлений, но это уже не обязательно, удвойте число возможных форматов до 18, изменяя положение запятой в шаблоне формата даты. Все эти изменения были сделаны для регулярного выражения выше. Протестируйте его измененную версию:
Измените регулярное выражение так, чтобы оно соответствовало вашим нуждам. Всегда проще сопоставлять образцы, логически связанные со своими входными данными, нежели рассогласованные с ними. Будущие поколения возможно увидят неприменимость предыдущего регулярного выражения из-за бага - Y10K, потому что максимально возможный год, который оно может найти - 9999. Сопоставление целых чиселКак видно в нескольких предыдущих примерах, числовой диапазон, заключенный в скобки, - хороший способ находить числа. Для сопоставления целых чисел любой длины за обозначением числового диапазона поставьте "+"; чтобы исключить отрицательные значения, поставьте перед обозначением диапазона специальный символ "-" (дефис):
Предыдущий пример успешно находит ноль, потому что ноль - одно из возможных значений в заданном промежутке. Заключение выражений в круглые скобки также хорошо для сопоставления чисел. Чтобы найти любое десятичное число, расширьте предыдущее регулярное выражение специальным вложением, содержащим десятичную точку, поставленную после одного или нескольких чисел:
Используйте скобки чтобы определить десятичное число с заданным количеством разрядов. Например, для поиска только положительных чисел с разрядностью 5 знаков до запятой:
Больше сопоставлений для реальных ситуацийОграничения на числовой диапазон, сопровождаемые метасимволами в скобках, полезны при поиске чисел какого-либо определенного формата. Собрав вместе все методы, описанные нами ранее, вы можете создать регулярные выражения, которые находят данные любых типов:
ЗаключениеЭта статья показала некоторые приемы создания шаблонов для написания регулярных выражений и возможности, где они могут использоваться для поиска отдельных типов данных, которые постоянно требуются администраторам. По ходу прочтения статьи вы познакомились с несколькими регулярными выражениями, вполне применимыми в повседневной работе. |