Диплом: Автоматизация "личного кабинета" консультанта по недвижимости (на примере организации Росинформ)

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам
73
регулярного выражения должен встретиться во входной строке для того чтобы
соответствие можно было бы считать истинным.
Следующая таблица иллюстрирует различные квантификаторы и их
значение:
Символ
Описание
*
Соответствует повторению предшествующего
подвыражения ноль или более раз. Например, 'zo*'
соответствует 'z' и 'zoo'. * является эквивалентом {0,}.
+
Соответствует повторению предшествующего
подвыражения один или более раз. Например, 'zo+'
соответствует 'zo' и 'zoo', но не 'z'. + является эквивалентом {1,}.
?
Соответствует повторению предшествующего
подвыражения ноль или один раз. Например, "do(es)?"
соответствует "do" в "do" или в "does". ? является эквивалентом
{0,1}.
{n}
n является положительным целым числом. Соответствует
точно n-ному количеству повторений. Например, 'o{2}' не
соответствует 'o' в "Bob", но соответствует 2-м символам 'o' в
"food".
{n,}
n является положительным целым числом. Соответствует
хотя бы n-ному количеству повторений. Например, 'o{2,}' не
соответствует "o" в "Bob", но соответствует всем 'o' в "foooood".
'o{1,}' является эквивалентом 'o+'. 'o{0,}' является эквивалентом
'o*'.
{n,m}
m и n это положительные целые числа, причем n <= m.
Соответствует хотя бы n-ому и не более чем m-ому числу
повторений. Например, "o{1,3}" соответствует первым трем 'o' в
"fooooood". 'o{0,1}' является эквивалентом 'o?'. Обратите
внимание, что Вы не можете поместить пробел между запятой и
цифрами.
74
В большом входном документе (речь идет о нашем примере с
заголовками глав), число глав может легко превысить девять, так что Вам
понадобится способ обработки двух или даже трех цифр в номере главы.
Квантификаторы дают Вам эту возможность. Следующее регулярное
выражение соответствует заголовкам глав с любым количеством цифр: "Chapter
[1-9][0-9]*"
Квантификатор располагается после выражения-диапазона. Поэтому он
применяется ко всему выражению диапазона, который, в данном случае,
определяет только цифры от 0 до 9, включительно.
Квантификатор '+' здесь не используется, потому что цифра не
обязательно должна иметься во второй или в последующих позициях. Символ
'?' также не используется, потому что он номера глав только до двух цифр. Вы
же хотите задать соответствие по крайней мере одной цифре после пробела,
следующего сразу за 'Chapter'.
Если Вы точно знаете, что максимальное количество глав ограничено
числом 99, Вы можете использовать следующее выражение , чтобы определить
по крайней мере одну, но не больше чем 2 цифры. "Chapter [0-9]{1,2}"
Недостаток выражения, показанного выше - то, что, если имеется номер
главы большее чем 99, оно все равно будет соответствовать только первым
двум цифрам. Другой недостаток - то, что кто-то мог создать и главу с номером
0 и это тоже будет соответствовать. Следующие выражения лучше для
соответствия только двум цифрам: "Chapter [1-9][0-9]?" или "Chapter [1-9][0-
9]{0,1}"
Квантификаторы '*', '+' и '?' - все являются, что называется жадными, то
есть они соответствуют максимально возможному объему текста. Иногда это
совсем не то, что Вы хотите получить. Иногда, Вы хотите только минимального
соответствия.
Скажем, Вы ищете в документе HTML вхождения заголовков,
помещенных в тэги H1. Этот текст выглядит в Вашем документе как:
75
<H1>Chapter 1 – Introduction to Regular Expressions</H1>
Следующее выражение соответствует всему, что расположено от
открывающего знака "меньше чем" (<) до того что размещено за символом
"больше чем" (>) в конце закрытого тэга H1.: "<.*>"
Если все, чему мы действительно хотели задать соответствие, был
открытый H1 тэг, следующее "нежадное" выражение соответствует только
<H1> "<.*?>"
Помещая '?' после квантификатора '*', '+' или '?', Вы преобразуете
выражение из "жадного" в "нежадное" (или соответствующее минимуму).
До сих пор примеры, которые мы рассматривали, касались только
обнаружения заголовков глав, где бы они не встречались. Любое вхождение
строки 'Chapter', за которой размещены сначала пробел, а затем цифра, могло
быть действительно заголовком этой главы или оно также могло оказаться
перекрестной ссылкой на другую главу. Так как истинные заголовки глав
всегда расположены в начале строки, Вам нужно будет придумать способ
чтобы находить только заголовки и не находить перекрестные ссылки.
Так называемые "якоря" обеспечивают эту возможность. Якоря
позволяют Вам прикрепить регулярное выражение к началу или к концу
строки. Они также позволяют Вам создавать регулярные выражения, которые
работают в пределах одного слова, а также в начале или в конце слова.
Следующая таблица содержит список якорей в регулярных выражениях и их
значения:
Символ
Описание
^
Соответствует позиции в начале входной строки. Если
свойство Multiline объекта RegExp установлено в значение True,
тогда символ ^ также соответствует и позиции, следующей за
'\n' или '\r'.
$
Соответствует позиции в конце входной строки. Если
свойство Multiline объекта RegExp установлено в значение True,
тогда символ $ также соответствует и позиции,
76
предшествующей '\n' или '\r'.
\b
Соответствует границе слова, то есть позиции между
словом и пробелом.
\B
Имеет значение, обратное соответствию границе слова
(не-граница слова).
Вы не можете использовать квантификатор для якоря. Так как Вы не
можете иметь больше одной позиции до или после символа новой строки или
границы слова, выражения подобные '^*' не допускаются.
Чтобы соответствовать тексту в начале текстовой строки, используйте в
начале регулярного выражения символ '^'. Не путайте данное применение '^' с
применением его в выражениях в квадратных скобках. Это абсолютно разные
вещи.
Чтобы соответствовать тексту в конце текстовой строки, используйте в
конце регулярного выражения символ '$'.
Для поиска заголовков глав, расположенных в начале строк и имеющих
номера из одной или двух цифр, применимо следующее регулярное выражение:
"^Chapter [1-9][0-9]{0,1}"
Мало того, что настоящий заголовок главы находится в начале строки,
он также является единственным объектом в строке, так что он должен быть
расположен также и в конце строки. Следующее выражение гарантирует, что
указанное Вами соответствие подойдет только к заголовкам, а не к
перекрестным ссылкам. Это реализовано созданием регулярного выражения,
которое жестко привязано и к начало и к концу строки текста. "^Chapter [1-9][0-
9]{0,1}$"
Соответствие границам слова работает несколько иначе, но оно
добавляет очень важную возможность к регулярным выражениям. Граница
слова - это позиция между словом и пробелом. Не-граница слова - любая другая
позиция. Следующее выражение для JScript соответствует первым трем
77
символам слова 'Chapter', потому что они следуют непосредственно за границей
слова: "\bCha"
Позиция оператора '\b' здесь очень критична. Если он расположен в
начале строки, которая будет соответствовать, соответствие будет отыскиваться
в начале слова; если он расположен в конце строки, соответствие будет
отыскиваться в конце слова. Например, следующие выражения соответствуют
'ter' в слове 'Chapter', потому что оператор введен перед границей слова: /ter\b/ и
"ter\b"
Следующее выражение соответствует фрагменту 'apt', если он находится
в 'Chapter', и не соответствует, если фрагмент находится в 'aptitude': "\Bapt"
Это происходит потому, что 'apt' встречается не на границе слова в слове
'Chapter', за то на границе слова в слове 'aptitude'. Для оператора не-границы
слова его позиция не играет важной роли, потому что соответствие не
привязано к началу или концу слова.
Символ вариации '|' используют для того чтобы допустить выбор между
двумя и более вариантами. Расширяя описанное ранее регулярное выражение
для поиска текста заголовков глав, можно изменить его так, что оно станет
соответствовать не только заголовкам глав. Однако, все не так просто и
прямолинейно, как Вы могли бы подумать. При использовании вариации
соответствовать будет самое большое возможное выражение с обеих сторон
символа '|'. Вы могли бы подумать, что следующие выражения для JScript и
VBScript соответствуют или слову 'Chapter' или слову 'Section', за которыми
следует одна или две цифры, и которые встречаются в начале или конце строки:
"^Chapter|Section [1-9][0-9]{0,1}$"
К сожалению, на самом деле выходит, что регулярные выражения,
показанные выше, соответствуют или слову 'Chapter' в начале строки, или слову
'Section' в конце строки, независимо от того, следуют ли за этим словом цифры.
Если входная строка - 'Chapter 22' тогда выражение, показанное выше,
соответствует только слову 'Chapter'. Если входная строка - 'Section 22', тогда
выражение соответствует 'Section 22'. Но это не совсем то, что мы хотели
78
реализовать, и здесь должен быть способ сделать так, чтобы регулярное
выражение стало более чувствительным к нашим запросам и такой способ
действительно существует.
Вы можете использовать круглые скобки для ограничения области
действия вариации, то есть для получения уверенности, что она применяется
только к этим двум словам, 'Chapter' и 'Section'. Однако, круглые скобки тоже не
так просты, потому что они кроме того используются и для создания
подвыражений (но это будет описано далее в соответствующем разделе
справки). Используя регулярные выражения, показанные выше и добавляя
круглые скобки в нужных местах, Вы сможете заставить регулярное выражение
соответствовать и 'Chapter 1' и 'Section 3'.
Следующие регулярные выражения используют круглые скобки для
группировки слов 'Chapter' и 'Section', поэтому выражение будет работать
должным образом.
"^(Chapter|Section) [1-9][0-9]{0,1}$"
Эти выражения работают нормально, но при этом обладают интересным
побочным эффектом. Когда мы помещаем 'Chapter|Section' внутрь круглых
скобок, мы организуем требуемую группировку, но кроме того это приводит к
тому, что одно из найденных соответствий будет сохранено (захвачено) для
будущего использования. Так как в выражениях, показанных выше,
присутствует только один набор с круглыми скобками, как следствие у нас
будет только одно найденное подсоответствие. Впоследствии можно будет
ссылаться на него, используя коллекцию в VBScript.
Иногда сохранение подсоответствия желательно, иногда - нет. В
примерах, показанных выше, все, что Вы действительно хотите сделать - это
использовать круглые скобки для создания альтернативного выбора между
словами 'Chapter' и 'Section'. Вы не обязательно хотите ссылаться позже на это
соответствие. Фактически, до того момента, когда вам действительно
понадобится сохранять подсоответствия, не пользуйтесь этой возможностью.
Ваши регулярные выражения будут более эффективны, так как они не будут
79
требовать дополнительного времени и памяти для обработки и сохранения этих
подсоответствий.
Вы можете использовать '?:' перед шаблоном регулярного выражения
внутри круглых скобок для предотвращения сохранения соответствия для
возможного будущего использования. Следующая далее модификация
регулярных выражений обеспечивает те же возможности без сохранения
подсоответстсвий.
"^(?:Chapter|Section) [1-9][0-9]{0,1}$"
В дополнение к метасимволам '?:', также существуют два других
"несохраняющих" метасимвола, которые используются для так называемого
"заглядывания вперед" (lookahead). Положительное соответствие с
заглядыванием вперед, задаваемое использованием метасимволов '?=',
соответствует разыскиваемой строке в любой точке где соответствующий
щаблон регулярного выражения в круглых скобках начинается search string at
any point where a matching regular expression pattern in parentheses begins.
Положительное соответствие с заглядыванием вперед, задаваемое
использованием метасимволов '?!', matches the search string at any point where a
string not matching the regular expression pattern begins.
Например, предположим, что у Вас есть документ, содержащий ссылки
на Windows 3.1, Windows 95, Windows 98 и Windows NT. Предположим далее,
что Вы должны модифицировать этот документ, находя все ссылки на Windows
95, Windows 98 и Windows NT и заменяя их ссылками на Windows 2000. Вы
можете использовать следующее регулярное выражение на JScript, которое
является примером положительного заглядыванием вперед, для задания
соответствия для Windows 95, Windows 98 и Windows NT:
/Windows(?=95 |98 |NT )/
Для того чтобы проделать тоже самое в VBScript, используйте
следующее:
"Windows(?=95 |98 |NT )"
80
Если соответствие найдено, поиск следующего соответствия начинается
непосредственно после найденного соответствия, без учета символов,
включенных в выражение с "заглядыванием вперед". Например, если
выражение, показанные выше соответствует 'Windows 98', поиск будет
продолжен после 'Windows', а не после '98'.
Одной из самых важных возможностей регулярных выражений является
возможность сохранения фрагмента, соответствующего шаблону, для
последующего его использования. Как вы помните, размещение круглых
скобок вокруг шаблона регулярного выражения, или части шаблона, приводит к
тому, что этот фрагмент выражения будет сохранен во временном буфере. Вы
можете предотвратить сохранение этого фрагмента регулярного выражения с
помощью использования нефиксирующих метасимволов '?:', '?=', или '?!'.
Все зафиксированные подсоответствия сохраняются в том порядке, как
они встретились в направлении слева направо в шаблоне регулярного
выражения. Номера буферов, хранящих найденные подсоответствия,
начинаются с 1 и продолжаются максимум до 99 подвыражений. К каждому
отдельному буферу можно обратиться, используя '\n', где n - одна или две
десятичных цифры, идентифицирующие определенный буфер.
Одно из самых простых и наиболее полезных применений обратных
ссылок позволяет обнаружить вхождение в тексте вместе двух идентичных
слов. Рассмотрим следующее предложение:
Is is the cost of of gasoline going up up?
Данное предложение явно имеет проблему с несколькими словами-
дубликатами. Было бы неплохо придумать способ определять это предложение
без необходимости производить поиск дубликатов каждого отдельного слова.
Следующее регулярное выражение на JScript использует единственное
подвыражение, чтобы реализовать это.
/\b([a-z]+) \1\b/gi
Эквивалентное выражение на VBScript:
"\b([a-z]+) \1\b"
81
Подвыражением в этом случае является все, что находится между
круглыми скобками. Это выражение состоит из одного или более алфавитного
символа, что определено с помощью '[a-z]+'. Вторая часть регулярного
выражения это ссылка на предыдущее зафиксированное подсоответствие, а
значит это - второе вхождение слова только что подошедшее под выражение в
скобках. '\1' используется для определения первого подсоответствия.
Метасимволы границ слова гарантируют, что будут обнаружены только
раздельные слова. Если же их не будет в выражении, тогда фраза типа "is
issued" или "this is" будет некорректно идентифицирована этим выражением.
В выражении JScript глобальный флаг ('g') после регулярного выражения
указывает на то, что выражение будет применяться к такому количеству
соответствий, сколько сможет найти во входной строке. Флаг
нечувствительности к регистру ('i') в конце выражения определяет
нечувствительность к регистра символов. Флаг мультистрочности определяет
то, что потенциальные соответствия могут происходить с обеих сторон символа
новой строки. Для VBScript многие флаги не могут быть установлены
непосредственно в выражении, а должны быть установлены явным образом в
свойствах объекта RegExp.
Используя регулярное выражение, показанное выше, следующий код
JScript может использовать информацию подсоответствия для замены вхождени
двух последовательных идентичных слов в строке текста на одиночное
вхождение того же самого слова:
var ss = "Is is the cost of of gasoline going up up?.\n";
var re = /\b([a-z]+) \1\b/gim; //Создаем образец для регулярного
выражения.
var rv = ss.replace(re,"$1"); //Заменяем два вхождения на одно.
Наиболее близкий эквивалент этого кода на VBScript выглядит
следующим образом:
Dim ss, re, rv
ss = "Is is the cost of of gasoline going up up?." & vbNewLine
82
Set re = New RegExp
re.Pattern = "\b([a-z]+) \1\b"
re.Global = True
re.IgnoreCase = True
re.MultiLine = True
rv = re.Replace(ss,"$1")
Обратите внимание, что в коде VBScript глобальный флаг,
мультистроковый флаг и флаг нечувствительности к регистру устанавливают,
используя соответственно названные свойства объекта RegExp.
Использование $1 внутри метода Replace создает ссылку на первое
сохраненное подсоответствие. Если Вы имеете более одного подсоответствия,
Вы доkжны ссылаться на них последовательно через $2, $3, и так далее.
Другое применение обратных ссылок состоит в возможности разобрать
Универсальный Индикатор Ресурса (URI) на составляющие его части.
Предположим, что Вы хотите разобрать следующий URI до следующих частей:
протокола (ftp, http, и т.д), доменного адреса и страницы/пути:
http://msdn.microsoft.com:80/scripting/default.htm
Следующие далее регулярные выражения обеспечивают эту
функциональность. Для JScript:
/(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)/
Для VBScript:
"(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)"
Первое заключенное в скобки подвыражение предназначено для
выделении протокола сети из сетевого адреса. Это подвыражение соответствует
любому слову, которое предшествует двоеточию и двум косым чертам. Второе
заключенное в скобки подвыражение предназначено для выделения доменной
части из сетевого адреса. Это подвыражение соответствует любой
последовательности символов, которая не включает символы '^', '/', или ':'.
Третье заключенное в скобки подвыражение отделяет номер порта, если он
определен. Подвыражение соответствует нулю или большему количеству цифр

Смотрите также:

"Автоматизация обработки заявок ООО "Проектно-Строительная Компания"
"Автоматизация процесса аттестации персонала для ООО "Нэт Бай Нэт Холдинг"
"Анализ интернет-активности конкурентов ( на примере конкурентов "Газпром нефть")
"Бухгалтерский учёт и аудит расчётов с подотчётними лицами в организации на примере ООО "ЛОЦ 10""
«Психологическое сопровождение персонала в организации на примере ООО «Крокус»
Cовершенствование деловой оценки персонала в организации (на примере ООО "Даймонд кейтеринг развитие")
IPO - инструмент финансирования деятельности организации. На примере ПАО «Нефтяная компания «Лукойл»
PR как средство продвижения организации (на примере ПАО "Тамбовский завод "Комсомолец им. Н.С. Артемова")
PR-коммуникации в сфере общественного питания (на примере кафе-кондитерской «Cream Cheese»)
SMM как средство повышения эффективности работы учреждений социокультурной сферы (на примере Малого театра)