Чтобы упростить ориентирование во все более разрастающемся Интернете, была разработана система DNS (Domain Name System - система именования доменов сети). Дело в том, что каждому компьютеру или компьютерной сети, подключенной к Интернету, назначается уникальная последовательность цифр, называемая IP-адресом.
IP-адрес состоит из четырех чисел, от 0 до 255 каждое, например 198.105.232.001. Зная IP-адрес, пользователь одного компьютера с легкостью находит другой компьютер в Интернете, и может к нему подключиться, если у него есть на это соответствующие права. Все просто, когда вам нужно получать доступ к одному-двум компьютерам, но если их количество переваливает за десяток или даже за сотню, а, тем более, если вам необходимо сообщать определенный IP-адрес многим людям, ситуация становится поистине кошмарной.
Избавиться от подобных проблем помогает система имен DNS. Она позволяет заменять цифровые IP-адреса на благозвучные буквенные, например: «microsoft.com» или «yandex.ru». Как же работает DNS? Все Интернет-пространство можно разделить на несколько групп, называемых «доменными зонами». Эти зоны называются доменами первого уровня. Разделение по зонам может проводиться как по географическому, так и по тематическому признаку. Географическая доменная зона определяет расположение компьютера в том или ином государстве. Вот несколько примеров географических доменов первого уровня: ru - Россия, fr - Франция, uk - Великобритания, jp - Япония, su - бывший Советский Союз. Тематические доменные зоны группируют компьютеры по информации, содержащейся на них, либо по типу организаций, ими владеющих, вне зависимости от их географического расположения.
Два компьютера, зарегистрированные в одной тематической доменной зоне, могут находиться в противоположных концах земного шара. Вот примеры тематических доменных зон: com - коммерческое предприятие, net - что-то связанное с сетевыми технологиями, edu - образовательное учреждение, info - информационный проект, gov - государственное учреждение, biz - бизнес-проект, mil - военная организация. Несмотря на обилие доменных зон, далеко не все из них пользуются большой популярностью. Основная часть компьютеров в Интернете зарегистрирована в доменных зонах com и net. Некоторые доменные зоны используются и вовсе не по прямому назначению. Например, островное государство Тувалу стало обладателем географической доменной зоны tv, которую сейчас облюбовали организации, так или иначе связанные с телевидением: телеканалы, производители бытовой техники, киноделы, рекламщики и прочие...
Каждая доменная зона делится на поддомены, или домены второго уровня, и каждому из этих поддоменов присваивается свое имя, например совпадающее с названием организации, владеющей доменом. Это имя приписывается к имени домена верхнего уровня слева, в виде суффикса, и отделяется точкой. Например, в имени microsoft.com строка com означает доменную зону, а суффикс microsoft - имя домена второго уровня. Как нетрудно догадаться, по этому адресу находится сеть, принадлежащая корпорации Microsoft. Однако сеть корпорации Microsoft весьма велика, поэтому каждый домен второго уровня, в свою очередь, может делиться еще на несколько подподдоменов, или доменов третьего уровня. Это записывается так - mail.microsoft.com. В этом примере mail - это суффикс домена третьего уровня. Такое деление может продолжаться до бесконечности, но обычно ограничивается доменами третьего-четвертого уровня.
Общее руководство и контроль над доменными зонами, осуществляет организация ICANN (The Internet Corporation for Assigned Names and Number - Интернет-ассоциация по выдаче имен и чисел). Она передает полномочия на выдачу адресов в той или иной доменной зоне другим организациям и следит за соблюдением основных правил. Организации, уполномоченные выдавать доменные адреса в той или иной доменной зоне, торгуют доменными адресами второго уровня. То есть, если кто-то хочет, чтобы у его компьютера в Интернет был адрес vasya-pupkin.com, он должен обратиться к организации, выдающей доменные имена в зоне com. Затем попросить зарегистрировать в ней домен второго уровня vasya-pupkin, предоставить IP-адрес своего компьютера в Сети и, разумеется, уплатить некоторую сумму денег. В результате, компьютер Васи в Интернете можно будет отыскать не только по малопонятному набору цифр IP-адреса, но и по звучному текстовому адресу.
При желании, одному IP-адресу можно сопоставить даже несколько доменных имен, например vasya-pupkin.com и vasiliy.ru. Адреса в Российской доменной зоне выдает организации РосНИИРОС, Российский НИИ развития общественных сетей.
Современный Интернет представляет собой сложнейшую систему из тысяч компьютерных сетей, объединенных между собой. Состоит эта система из двух основных элементов: узлов сети Интернет и соединяющих их информационных магистралей. Узлом Интернета называют любое устройство, имеющее свой IP-адрес и подключенное к Сети. Несмотря на кажущуюся мешанину межкомпыотерных соединений и отсутствие централизованного руководства, Интернет имеет определенную иерархическую структуру.
В самом низу иерархии находится многочисленная армия конечных пользователей. Часто не имеющие даже постоянного IP-адреса подключаются к Интернету по низкоскоростным каналам. Тем не менее, пользователи являются одними из основных потребителей услуг Сети и главными «спонсорами» коммерческой части Интернета. Причем на одного «физического» пользователя, т. е. реального человека, пользующегося услугами Сети, может приходиться несколько пользователей «логических», т. е. различных подключений к Интернету.
Так, кроме компьютера, возможность подключения к Интернету может иметь мобильный телефон, карманный компьютер, бытовая техника, автомобиль и даже кондиционер. Конечные пользователи подключаются к компьютерам Интернет-провайдера, или, как их еще называют, ISP (Internet Service Provider - провайдер Интернет). ISP - это организация, основная деятельность которой связана с предоставлением услуг Интернета пользователям.
У провайдера есть своя компьютерная сеть, размеры которой могут варьироваться от сотен десятков узлов в нескольких городах до многих тысяч, раскиданных по целому континенту. Эта сеть называется магистральной сетью, или бэкбоном (от слова backbone - стержень, магистраль). Сети отдельных провайдеров соединяются между собой и другими сетями. Среди ISP есть «монстры», которые обеспечивают соединение между собой сетей различных стран и континентов, являясь своего рода «провайдерами для провайдеров». Весь этот конгломерат компьютерных сетей и образует то, что называется Интернетом.
Особняком стоят DNS-серверы - компьютеры, отвечающие за функционирование системы DNS. Для подключения конечных пользователей к ISP служат так называемые «точки доступа» - компьютеры или специальные устройства, содержащие оборудование для подключения «извне».
Подключившись к точке доступа провайдера, пользователь становится частью магистральной сети провайдера и, соответственно, получает доступ к ее ресурсам, а также к ресурсам сетей, соединенных с бэкбоном провайдера, т. е. ко всему Интернету. Кроме конечных пользователей, к сети провайдеров подключаются различного рода серверы, или «хосты» (от слова host - хозяин). Это узлы сети, на которых работает программное обеспечение, обеспечивающее практически все услуги, предоставляемые сетью Интернет.
Вторая часть серии статей "Использование регулярных выражений в PHP" посвящена решению ряда проблем обработки сложных текстов с помощью "продвинутых" операторов регулярных выражений.
Несмотря на то, что термины данные и информация используются взаимозаменяемо, между ними есть существенная разница. Данные существуют реально. Данные — - это список температур, перечень недавних продаж или опись товара, имеющегося в наличии. Информация — это прогнозы. Информация — это предсказание погоды, прогноз прибылей и убытков и тенденции сбыта. Данные записываются в виде нулей и единиц, в то время как информация обрабатывается мозгом.
Между данными и информацией располагается приложение: механизм, который преобразует одно в другое и наоборот. Например, при покупке книги в Интернете это приложение преобразует вашу информацию — название книги, идентификатор, информацию о банковском счете — в данные: номер заказа, цену со скидкой, характеристики транзакции с использованием кредитной карточки и количество оставшихся в наличии экземпляров книги. Аналогичным образом, приложение преобразует данные в запрос на выборку со склада, отметку об отгрузке и номер отслеживания — информацию, необходимую для реализации продажи.
В действительности сложность создания приложения прямо пропорциональна преобразованиям, которые оно выполняет. Гостевая книга Web-сайта, передающая имя и адрес в поля базы данных, устроена элементарно. С другой стороны, онлайновый магазин, который передает большое количество видов информации в модель данных коммерческой сделки и преобразует данные в информацию для реализации процесса принятия решений, достаточно сложен с точки зрения разработки. Искусство программирования заключается в умелом манипулировании данными и информацией — мастерство, схожее с фиксацией света в живописи.
Как было сказано в первой части, регулярные выражения являются одним из самых мощных средств манипулирования данными. Регулярные выражения лаконично описывают форму данных и раскладывают их на составляющие. Например, следующее регулярное выражение можно использовать для обработки температуры, заданной в градусах по Цельсию или по Фаренгейту: /^([+-]?[0-9]+)([CF])$/.
Регулярное выражение сравнивает начало строки (отображается знаком "крышка" (^), за которым идет знак "+", знак "-", или ничего ([+-]?), за которым следует целое число ([0-9]+), обозначение шкалы — Цельсия или Фаренгейта ([CF]) — и заканчивается концом строки (обозначается знаком доллара $).
В данном регулярном выражении операторы начала строки и конца строки представляют собой примеры операторов нулевой ширины или совпадений по положению, а не по символам. Круглые скобки также не указывают на символы. Зато, если заключить шаблон в круглые скобки, то будет извлечен текст, соответствующий шаблону. Следовательно, если текст полностью сопоставим с шаблоном, то первая пара круглых скобок выдаст строку, представляющую собой положительное или отрицательное целое число, например, +49, а вторая пара круглых скобок - или букву C, или F.
В первой части серии представлено понятие регулярного выражения и были описаны PHP-функции для сравнения текста с шаблонами, а также для извлечения совпадений. А теперь давайте углубимся в изучение регулярных выражений и посмотрим на некоторые "продвинутые" операторы и средства.
Круглые скобки опять приходят на помощь
В большинстве случаев пара круглых скобок используется для описания части шаблона и получения текста, соответствующего этой части. Однако от круглых скобок не всегда требуется получение части шаблона. Как и в сложной арифметической формуле, круглые скобки можно использовать для группировки условий.
Приведу пример. Догадаетесь, какому типу данных соответствует данное выражение?
/[-a-z0-9]+(?:\.[-a-z0-9]+)*\.(?:com|edu|info)/i
Как можно догадаться, это регулярное выражение определяет имена Интернет-сайтов (только для доменов .com, .edu, и .info). Отличием является использование дополнительного оператора ?:. Квалификатор части шаблона ?: отключает функцию извлечения данных, и тем самым дает круглым скобкам возможность обозначать последовательность действий. Например, в данном случае фраза (?:\.[-a-z0-9]+)* соответствует нулю или более элементам строки, например, ".ibm." Аналогично, фраза \.(?:com|edu|info) обозначает последовательность символов, за которой идет одна из строк com, edu, или info.
Отключение функции извлечения информации может показаться бессмысленным, если не подумать о том, что извлечение информации требует дополнительной обработки. Если программа обрабатывает большое количество данных, то отказ от извлечения может быть целесообразным. Кроме того, если вы имеете дело со сложным регулярным выражением, то отключение функции извлечения информации в некоторых частях шаблона может упростить извлечение тех частей шаблона, которые реально нужны.
Примечание: Модификатор i в конце регулярного выражения делает все сопоставления с шаблоном нечувствительными к регистру. Следовательно, подмножество a-z будет сопоставимо со всеми буквами, независимо от регистра.
В PHP есть и другие модификаторы частей шаблона (subpattern). Используя отладчик регулярных выражений, показанный в первой части данной серии (повторно показан в листинге 1), попробуйте сопоставить регулярное выражение ((?i)edu) со строками "EDU," "edu," и "Edu." Если в начале части шаблона задать модификатор (?i), то сопоставление с шаблоном не будет зависеть от регистра. Чувствительность к регистру восстанавливается, как только заканчивается данная часть шаблона. (Сравните с модификатором / ... /i, который применяется ко всему шаблону.)
Листинг 1. Простой отладчик регулярных выражений
Еще один полезный модификатор части шаблона - это (?x). Он позволяет добавлять в шаблон пробелы, что упрощает чтение регулярных выражений. Таким образом, часть шаблона ((?x) edu | com | info) (обратите внимание на пробелы между операторами дизъюнкции, которые добавлены для удобочитаемости) аналогична (edu|com|info). Для того, чтобы добавлять пробелы и комментарии в регулярное выражение, можно использовать глобальный модификатор / ... /x, см. листинг ниже.
Листинг 2. Добавление пробелов и комментариев
Как видно из листинга, при необходимости модификаторы можно объединять. Если необходимо включить в регулярное выражение символ пробела при использовании модификатора (?x), используйте метасимвол \s для поиска любого пробельного символа и \ (обратный слеш с пробелом) для поиска одного пробела, например, ((?x) hello \ there).
Оглядываемся вокруг
В подавляющем большинстве случаев регулярные выражения используются для проверки или декомпозиции входной информации на отдельные "лакомые кусочки", которые записываются в архив данных или сразу же обрабатываются приложением. Общепринятыми сферами применения являются: обработка полей форм, парсинг XML-кода и анализ протоколов.
Еще одна область применения регулярных выражений - форматирование, нормализация или улучшение читаемости данных. Вместо того чтобы использовать регулярные выражения для поиска и извлечения текста, при форматировании они применяются для поиска и вставки текста в надлежащее местоположение.
Вот пример полезного применения форматирования. Предположим, что Web-форма передает приложению значение зарплаты с округлением до целого доллара. Так как зарплата хранится в виде числа целого типа, то перед сохранением переданных данных приложение должно удалять из них знаки пунктуации. Однако при извлечении данных из хранилища, возможно, понадобится изменить их формат и сделать удобочитаемыми с помощью разделителей. В листинге 3 показано, как простой PHP-запрос преобразует сумму в долларах в число.
Листинг 3. Преобразование суммы в долларах в число
Вызов функции preg_replace() заменяет знак доллара, любой пробельный символ и все запятые -- на пустую строку, возвращая то, что предположительно является целым числом. Если проверка функцией is_numeric() подтверждает правильность входных данных, их можно сохранить.
А теперь давайте выполним обратную операцию - добавим к числу знак денежной единицы и запятые-разделители сотен, тысяч и миллионов. Для добавления запятых в определенных позициях можно написать программу для поиска этих компонентов, а можно воспользоваться операторами посмотри вперед и посмотри назад. Модификатор части шаблона ?<= обозначает посмотри назад (то есть влево) от текущей позиции. Модификатор ?= означает "посмотри вперед" (то есть вправо) от текущей позиции.
[pagebreak]
Итак, какие позиции нам нужны? Любое место в строке, при условии, что есть как минимум один символ слева и одна или более групп по три символа справа, не считая десятичной точки и количества центов. Соблюдая это правило и используя два модификатора, анализирующих символы справа и слева от определенной позиции и являющихся операторами нулевой ширины, мы можем достичь цели с помощью следующей инструкции:
Как работает это регулярное выражение? Начиная с первого символа строки и обрабатывая каждый символ, регулярное выражение отвечает на вопрос: "Есть ли хотя бы один символ слева и одна или несколько групп из трех символов справа?" Если да, то наш оператор нулевой ширины заменяется запятой.
Большинство сложных сопоставлений можно реализовать, используя стратегию, аналогичную приведенной выше. Например, вот еще один вариант использования оператора "посмотри вперед", который решает широко распространенную дилемму.
Листинг 4. Пример использования оператора "посмотри вперед" ("предвидение")
Оператор preg_replace() преобразует строку данных, разделенных запятыми, в строку данных, разделенных знаком табуляции. Предусмотрительным образом, он не заменяет запятые в строке, заключенной в кавычки.
Это регулярное выражение при каждом обнаружении запятой (на это указывает запятая в самом начале регулярного выражения) проверяет утверждение: "Впереди не было кавычек или было четное количество кавычек". Если утверждение верно, то запятую можно заменить знаком табуляции (the \t).
Если Вам не нравятся операторы «посмотри вперед» и «посмотри назад» или вы работаете с таким языком, в котором их нет, можно добавить запятые в число и с помощью обычного регулярного выражения. Однако для реализации такого решения потребуется много итераций.
Листинг 5. Добавление запятых
Давайте пройдем по коду. Сначала параметр зарплаты очищается от знаков пунктуации для моделирования ситуации чтения целого числа из базы данных. Затем выполняется цикл в поисках позиций, где за одним числовым символом ((\d) идут три числовых символа ((\d\d\d\): если обнаруживается граница слова, заданная как \b, цикл прекращается. Граница слова -- это еще один оператор нулевой ширины, который соответствует следующим позициям:
* Перед первым символом строки, если это буква слова.
* За последним символом строки, если это буква слова.
* Между буквой слова и небуквенным символом, непосредственно за буквой слова.
* Между небуквенным символом и буквой слова, непосредственно за небуквенным символом.
Таким образом, примерами правильных границ слова являются пробел, точка и запятая.
Благодаря внешнему циклу регулярное выражение перемещается слева направо в поисках цифры, за которой идут три цифры и граница слова. При обнаружении совпадения между двумя частями шаблона добавляется запятая. Цикл должен продолжаться до тех пор, пока оператор preg_replace() находит совпадения, что задано в условии $old != $pretty_print.
Жадность и лень
Регулярные выражения обладают большими возможностями, иногда даже слишком большими. Например, давайте рассмотрим, что произойдет, если регулярное выражение ".*" будет обрабатывать строку "The author of 'Wicked' also wrote 'Mirror, Mirror.'" Вероятно, вы предполагаете, что preg_match() вернет два совпадения, и с удивлением обнаружите, что результат всего один: 'Wicked' also wrote 'Mirror, Mirror.'
Почему? Если не задать иное, то такие операторы как * (ноль или более) и + (один или более) -- "жадные". Если сопоставление с образцом может продолжаться, то они и будут его продолжать до тех пор, пока не будет возвращен максимальный результат из возможных. Для сохранения минимальных совпадений необходимо принудительно заставлять определенные операторы быть "ленивыми". "Ленивые" операторы находят самое короткое совпадение и на этом останавливаются. Чтобы сделать оператор более "ленивым", добавьте суффикс в виде знака вопроса. Пример показан в листинге 6.
Листинг 6. Добавление суффикса в виде знака вопроса
Регулярное выражение ".*?" расшифровывается следующим образом: "найти кавычку, за которой идет ровно столько символов с последующей кавычкой.
Однако иногда оператор * может быть слишком "ленивым". Например, посмотрите на следующий фрагмент кода. Что он делает?
Листинг 7. Простой отладчик регулярных выражений
Что вы загадали? "123"? "1"? Нет результата? На самом деле результатом будет Array ( [0] => [1] => ), означающий, что совпадение было найдено, но никаких данных извлечено не было. Почему? Вспомните, что оператор * ищет совпадения с нулем или более символов. В данном случае, выражение [0-9]* находит совпадение с нулем символов от начала строки, и обработка заканчиваетс.
Для решения данной проблемы добавьте оператор нулевой ширины для привязки совпадения, который заставляет регулярное выражение продолжать сопоставления; /([0-9]*\b/.
Советы и рекомендации
С помощью регулярных выражений можно решать как простые, так и сложные задачи при обработке текста. Начните с небольшой группы операторов и по мере того, как вы будете набираться опыта, расширяйте свой словарь. В качестве вознаграждения за ваши старания -- некоторые советы и рекомендации.
Создание переносимых регулярных выражений с помощью классов символов
Вам уже знакомы метасимволы, например, \s - соответствует любому пробельному символу. Кроме того, большинство реализаций регулярных выражений поддерживает предопределенные классы символов, которые более просты в использовании и переносимы с одного письменного языка на другой. Например, класс символов [:punct:] замещает все символы пунктуации в данном языке. Вместо [0-9] можно использовать [:digit:] и более переносимое замещение [:alpha:] вместо [-a-zA-Z0-9_]. Например, можно убрать все знаки пунктуации, используя:
Класс символов представляет собой более сжатую форму по сравнению с подробным описанием всех символов пунктуации. Полный перечень классов символов можно найти в документации по версии языка PHP.
Как исключить то, что вы не ищете
Как показано в примере с данными, разделенными символом табуляции, в качестве значений, разделенных запятыми (CSV), иногда проще и точнее задать список тех вариантов, которые не нужно находить (сопоставлять). Последовательность, начинающаяся со знака "крышка" (^) будет соответствовать любому символу, не принадлежащему данной последовательности. Например, для проверки правильности телефонных номеров для США можно использовать регулярное выражение /[2-9][0-9]{2}[2-9][0-9]{2}[0-9]{4}/. Используя набор ограничений можно написать регулярное выражение в более явном виде /[^01][0-9]{2}[^01][0-9]{2}[0-9]{4}/. Оба регулярных выражения работают, хотя смысл последнего, вероятно, более понятен.
Пропуск новой строки
Если во входных данных несколько строк, стандартного регулярного выражения будет недостаточно, так как сканирование прекращается на начале новой строки, которая обозначается $. Однако, если воспользоваться модификаторами s или m, то регулярное выражение будет обрабатывать входные данные по-другому. Первый модификатор рассматривает строковую последовательность как одну строку, где точка указывает на начало новой строки (обычно она этого не делает). Второй рассматривает строковую последовательность как несколько строк, где ^ и $ соответствуют началу и концу любой строки, соответственно. Приведем пример. Если задать $string = "Hello,\nthere";, то оператор preg_match( "/.*/s", $string, $matches) параметру $matches[0] присвоит значение Hello,\nthere. (При удалении s будет выдано Hello.)
Поиск по шаблону является настолько обычным занятием в разработке программного обеспечения, что для облегчения этой задачи была создана специальная технология — регулярные выражения. Узнайте, как можно использовать ее при написании кода, прочитав эту статью.
Все устройства получают входную информацию, выполняют какие-либо операции и выдают результат. Например, телефон во время разговора преобразует звуковую энергию в электрический сигнал и обратно. Двигатель потребляет топливо (пар, расщепление атомных ядер, бензин, мышечные усилия) и преобразует его в энергию. Блендер поглощает ром, лед, лайм и кюрасао и взбалтывает их в коктейль Mai Tai. (Или, если вам хочется чего-то изысканного, сделайте Bellini из шампанского и грушевого сока. Блендер – замечательное универсальное устройство.)
Так как программное обеспечение преобразует данные, то каждое приложение фактически является устройством (хоть и виртуальным, так как у него нет физических составляющих). Например, компилятор в качестве входной информации получает исходную программу и преобразует ее в двоичный исполняемый код. Программа прогнозирования погоды генерирует предсказания на основе результатов прошлых (исторических) замеров, а графический редактор обрабатывает пикселы, применяя правила к отдельным пикселам или их группам, чтобы, например, сделать изображение более четким или изменить его стиль.
Так же, как и любое другое устройство, программное обеспечение предназначено для работы с определенным исходным материалом, например, набором чисел, данными XML-схемы или протоколом. Если программе задать некорректную входную информацию — неподходящую по форме или типу, то существует большая вероятность того, что результат будет непредсказуемым и, возможно, даже катастрофическим. Как говорится: "Мусор заложишь - мусор получишь".
На самом деле для решения всех нетривиальных задач необходимо отделять правильные данные от некорректных и отклонять некорректные данные во избежание ошибок в результатах. Это, конечно же, актуально и для Web-приложений, написанных на языке PHP. Неважно, получены ли входные данные из формы для ввода с клавиатуры или в результате выполнения программного запроса Asynchronous JavaScript + XML (Ajax), прежде чем начать какие-либо вычисления, программа должна проверить входную информацию. Возможно, что числовые значения должны находиться в пределах определенного диапазона чисел или представлять собой только целые числа. Возможно, значение должно соответствовать определенному формату, например, почтового индекса. Например, почтовый индекс в США представляет собой пять цифр плюс дополнительный префикс "Plus 4", состоящий из дефиса и 4 дополнительных цифр. Возможно, другие строки также должны состоять из определенного количества символов, например, две буквы для указания аббревиатуры штата США. Строковые данные доставляют особенно много проблем: PHP-приложение должно быть начеку по отношению к злонамеренным программам-агентам, вложенным в SQL-запросы, код JavaScript или любой другой код, которые способны изменить поведение приложения или обойти защиту.
Однако каким образом программа может определить, являются ли входные данные числом или соответствуют ли определенным требованиям, например, к почтовому индексу? На самом деле для реализации проверки путем сопоставления с шаблоном необходим небольшой парсер, создающий конечный автомат, считывающий входные данные, обрабатывающий маркеры, отслеживающий состояние и выдающий результаты. Однако создание и обслуживание даже самого простого парсера может оказаться непростым делом.
К счастью, анализ на основе сопоставления с шаблоном настолько широко распространен в компьютерных технологиях, что с течением времени (примерно с момента появления UNIX®) были разработаны специальные технологии и, конечно же, механизмы обработки, чтобы облегчить рутинную работу. Регулярное выражение (regex) описывает шаблоны посредством лаконичных и удобочитаемых обозначений. Получив регулярное выражение и данные, механизм regex сообщает, совпадают ли эти данные с шаблоном, и если совпадение было обнаружено, что именно совпало.
Вот небольшой пример использования регулярного выражения, взятый из UNIX-утилиты, работающей в режиме командной строки, которая ищет заданный шаблон в содержимом одного или нескольких текстовых файлов UNIX. Команда grep -i -E '^Bat' ищет последовательность символов beginning-of-line (начало строки), обозначаемое "крышкой", [^]), за которым следуют буквы b, a, и t верхнего или нижнего регистра (ключ -i указывает на то, что при сопоставлении с шаблоном регистр не учитывается, таким образом, например, B и b - тождественны). Следовательно, для файла heroes.txt:
Листинг 1. heroes.txt
Вышеупомянутая команда grep выдаст два совпадения:
Batman
Batgirl
Регулярные выражения
PHP предлагает два программных интерфейса регулярных выражений: один -- для интерфейса переносимых операционных систем (POSIX), а второй - для регулярных выражений, совместимых с языком Perl (PCRE). В общем и целом второй интерфейс является более предпочтительным, так как PCRE сам по себе мощнее, чем POSIX, и предоставляет все операторы, используемые в языке Perl. Более подробная информация по обращению к regex-функциям POSIX представлена в документации по языку PHP (см. раздел Ресурсы). В данной статье мы сосредоточим свое внимание на свойствах PCRE.
Регулярные выражения PHP PCRE содержат операторы, позволяющие путем сопоставления находить конкретные символы или другие операторы, определенные местоположения, например, начало и конец строки, начало или конец слова. Регулярные выражения также позволяют описывать альтернативы, которые можно задать альтернативы типа "или"-"или"; повторения фиксированной, изменяемой или неопределенной длины; наборы символов (например, "любая буква от a до m"); и классы, или типы символов (печатаемые символы, знаки препинания). Специальные операторы также разрешают использовать группировку — возможность применить оператор к целой группе других операторов.
В таблице 1 показаны некоторые типичные операторы регулярных выражений. Для создания сложных выражений можно последовательно объединять элементарные операторы из таблицы 1 (и другие).
Таблица 1. Типичные операторы регулярных выражений
Оператор Значение
. (точка) Любой одиночный символ
^ (крышка) Пустая последовательность в начале строки или цепочки
$ (знак доллара) Пустая последовательность в конце строки
A Буква A верхнего регистра
a Буква a нижнего регистра
\d Любая цифра
\D Любой нецифровой символ
\w Любая буква или цифра; синоним - [:alnum:]
[A-E] Любая заглавная буква из A, B, C, D или E
[^A-E] Любой символ, за исключением заглавных букв A, B, C, D или E
X? Найти совпадение по отсутствию или наличию одной заглавной буквы X
X* Ни одной или любое количество заглавных букв X
X+ Одна или несколько заглавных букв X
X{n} Ровно n заглавных букв X
X{n,m} Не менее n и не более m заглавных букв X; если опустить m, то выражение будет искать не менее n заглавных букв X
(abc|def)+ По меньшей мере одно вхождение последовательности abc и def
В следующем примере показано типичное использование регулярного выражения. Например, для web-сайта необходимо, чтобы каждый пользователь регистрировался. Имя пользователя должно начинаться с буквы и содержать от 3 до 10 буквенно-цифровых символов. Для проверки имени пользователя на соответствие ограничениям при отправке данных в приложение можно использовать следующее регулярное выражение: ^[A-Za-z][A-Za-z0-9_]{2,9}$.
Знак "крышка" соответствует началу строки. Первый набор [A-Za-z] соответствует любой букве. Второй набор [A-Za-z0-9_]{2,9} соответствует последовательности, содержащей от 2 до 9 букв, цифр или символов подчеркивания. Знак доллара ($) соответствует концу строки.
На первый взгляд, знак доллара может показаться лишним, однако его использование важно. Если его пропустить, то условиям данного регулярного выражения будет отвечать любая строка, которая начинается с буквы, содержит от 2 до 9 буквенно-цифровых символов и любое количество других символов. Иными словами, если бы не было знака доллара как привязки к концу строки, то подошла бы недопустимо длинная строка с подходящим началом, например, "martin1234-cruft" .
Программирование на языке PHP и регулярные выражения
В PHP есть функции для поиска совпадений в тексте, замены каждого совпадения на другой текст (похоже на операцию "найти и заменить") и поиска совпадений среди элементов списка. Вот эти функции:
Чтобы показать, как работают эти функции, давайте создадим небольшое PHP-приложение, которое будет просматривать список слов на соответствие определенному шаблону. Слова и регулярные выражения будут вводиться из обычной web-формы, а результаты отображаться в браузере посредством функции simple print_r(). Эта программка пригодится, если возникнет желание проверить или отладить регулярное выражение.
PHP-код показан в листинге 2. Все входные данные берутся из обычной HTML-формы. (Для краткости эту форму и PHP-код, отслеживающий ошибки, опустим.)
Листинг 2. Сравнение текста с шаблоном
Вначале с помощью функции preg_split() строка из слов, разделенных запятыми, преобразуется в отдельные элементы. Данная функция разбивает строку в тех местах, которые соответствуют условиям регулярного выражения. В данном случае регулярное выражение представляет собой просто "," , (запятая - разделитель списка слов, указанных через запятую). Слэш в начале и в конце просто показывает начало и конец regex.
Третий и четвертый аргументы функции preg_split() необязательны, но полезны. Добавьте в третий аргумент число n целого типа, если необходимо вернуть только первые n совпадений, или -1, если необходимо вернуть все совпадения. Если в качестве четвертого аргумента задать идентификатор PREG_SPLIT_NO_EMPTY, то функция preg_split() не будет возвращать пустые результаты.
Затем каждый элемент списка слов, разделенных запятыми, корректируется (убираются начальные и конечные пробелы) с помощью функции trim() и сравнивается с заданным регулярным выражением. Функция preg_grep() существенно упрощает процесс обработки списка: просто укажите в качестве первого аргумента шаблон, а в качестве второго - массив слов для сравнения. Функция возвращает массив совпадений.
Например, если в качестве шаблона задать регулярное выражение ^[A-Za-z][A-Za-z0-9_]{2,9}$ и список слов разной длины, то можно получить результат, показанный в листинге 3.
Листинг 3. Результат работы простого регулярного выражения
Кстати, с помощью дополнительного маркера PREG_GREP_INVERT можно инвертировать операцию preg_grep() и найти элементы, которые не совпадают с шаблоном (аналогично оператору grep -v в командной строке). Заменяя 22 строку на $matches = preg_grep( "/${_REQUEST[ 'regex' ]}/", $words, PREG_GREP_INVERT ) и используя входные данные из листинга 3, мы получим Array ( [1] => 1happy [2] => hermanmunster ).
Разбор строк
Функции preg_split() и preg_grep() очень удобны. Первая из них может разбирать строку на подстроки, если подстроки разделяются определенным шаблоном. Функция preg_grep() позволяет быстро отфильтровать список.
Но что произойдет, если строку нужно разобрать на составные части, используя одно или несколько сложных правил? Например, в США номера телефонов обычно выглядят следующим образом: "(305) 555-1212," "305-555-1212," или "305.555.1212." Если убрать пунктуацию, то количество символов сократится до 10 цифр, что легко можно определить с помощью регулярного выражения \d{10}. Однако код и префикс (каждый из которых состоит из трех цифр) телефонного номера США не могут начинаться с нуля или единицы (так как нуль и единица используются как префиксы для междугородных звонков). Вместо того чтобы разбивать числовую последовательность на отдельные цифры и создавать сложный код, для верификации можно использовать регулярное выражение.
Фрагмент кода позволяющий решить эту задачу, показан в листинге 4.
Листинг 4. Проверка американского телефонного номера
Давайте пройдем по этому коду:
* Как показано в таблице 1, в регулярных выражениях используется ограниченный набор специальных символов, например, квадратные скобки ([ ]) для наименования последовательности. Если надо найти такой символ в тексте, необходимо "выделить" специальный символ в регулярном выражении, поставив перед ним обратный слэш (\). Когда символ выделен, можно задать его посик, как и любого другого символа. Если нужно найти символ точки, например, в полном составном имени хоста, то напишите \.. При желании строку можно подать в функцию preg_quote() которая выполняет автоматическую изоляцию всех специальных символов регулярных выражений, как показано в строке 1. Если поставить echo() $punctuation после первой строки, то вы должны увидеть \(\)\.-.
* В строке 2 из телефонного номера убираются все знаки пунктуации. Функция preg_replace() заменяет все символы из $punctuation — операторы из набора [ ] - пустой строкой, эффективно устраняя такие символы. Возвращаемая новая строка присваивается переменной $number.
* В строке 4 определен шаблон верифицируемого телефонного номера США.
* Строка 5 реализует сопоставление, сравнивая телефонный номер, который теперь состоит только из цифр, с шаблоном. Функция preg_match() возвращает 1, если есть совпадение. Если совпадения нет, функция preg_match() возвращает нулевое значение. Если во время обработки возникла ошибка, то функция возвращает значение False (ложно). Таким образом, чтобы проверить удачное завершение, необходимо посмотреть, было ли возвращено значение 1. В противном случае проверьте итоговое значение функции preg_last_error() (если используется PHP версии 5.2.0 или выше). Если оно не равно нулю, то, возможно, был превышен лимит вычислений, например, разрешенная глубина рекурсии регулярного выражения. Обсуждение констант и ограничений, применяемых в регулярных выражениях PHP, представлено на странице, посвященной функциям регулярных выражений PCRE (см. раздел Ресурсы).
Извлечение данных
Во многих случаях необходимо только получить ответ на вопрос: "Соответствуют ли данные шаблону?" – например, при проверке данных. Однако чаще регулярные выражения используются для подтверждения соответствия и получения информации о совпадении.
Вернемся к примеру с телефонным номером. Пусть при соответствии шаблону нам необходимо сохранить код, префикс и номер линии в отдельных полях базы данных. Регулярные выражения могут запоминать совпадающие с шаблоном данные с помощью оператора capture. Оператор capture обозначается круглыми скобками и может использоваться в любой части регулярного выражения. Операции capture можно делать вложенными для поиска подсегментов в извлеченных сегментах данных. Например, чтобы из 10-значного номера телефона извлечь код города, префикс и номер линии, можно использовать следующую строку:
/([2-9][0-9]{2})([2-9][0-9]{2})([0-9]{4})/
Если входные данные соответствуют шаблону, первые три цифры захватываются первой парой круглых скобок, следующие три цифры - второй парой, а последние 4 цифры - последним оператором. Модификация вызова функции preg_match() возвращает извлеченные данные.
Листинг 5. Возврат извлеченных данных функцией preg_match()
Если в качестве третьего аргумента функции preg_match() указать переменную, например, в нашем коде, $matches, то в качестве ее значения будет выступать список извлеченных результатов. Нулевой элемент списка (с индексом 0) - это все совпадение целиком; первый элемент - совпадение, относящееся к первой паре круглых скобок, и так далее.
Вложенные операторы capture извлекают сегменты и подсегменты фактически любой глубины. Сложность с вложенными операторами capture состоит в том, чтобы определить, в какой части массива соответствий находится каждое соответствие, например, $matches. Действует следующее правило: подсчитайте порядковый номер открывающей скобки в регулярном выражении — этот номер и будет индексом нужного совпадения в массиве соответствий.
В листинге 6 показан пример (немного надуманный) извлечения частей городского адреса.
Листинг 6. Код для извлечения городского адреса
Опять все совпадение целиком хранится по индексу 0. А где хранится номер улицы? Если считать слева направо, номер улицы проверяется \d+. Это вторая открывающая круглая скобка слева, следовательно, значением $matches[2] будет 123. В $matches[4] оказывается название города, а в $matches[6] - почтовый индекс.
Продвинутые технологии
Обработка текста – широко распространенная задача, и PHP предоставляет ряд функций, упрощающих выполнение большого числа операций. Обратите внимание на следующее:
* Функция preg_replace() может работать как с одной строкой, так и с массивом строк. Если вызвать preg_replace() для массива строк, замена будет выполнена во всех элементах массива. В этом случае код preg_replace() возвращает массив измененных строк.
* Как и во всех остальных реализациях PCRE, здесь для осуществления замены можно прибегать к сравнению с вложенным шаблоном. Для наглядности давайте рассмотрим проблему стандартизации формата телефонного номера. Заменим все знаки пунктуации точками. Наше решение показано в листинге 7.
Листинг 7. Замена знаков пунктуации точками
Сопоставление с шаблоном и, в случае совпадения, перевод в стандартный телефонный номер выполняется за один шаг.
Извлечение изображения из BLOB-поля таблицы dBASE или Paradox -- без первой записи изображения в файл -- простейший процесс использования метода Assign для сохранения содержимого BLOB-поля в объекте, имеющим тип TBitmap. Отдельный объект TBitmap или свойство Bitmap объекта Picture, в свою очередь являющегося свойством компонента TIMage, могут служить примером совместимой цели для данной операции.
Вот пример кода, демонстрирующего использование метода Assign для копирования изображения из BLOB-поля в компонент TImage.
В данном примере, объект Table1Bitmap типа TBLOBField - BLOB-поле таблицы dBASE. Данный TBLOBField-объекты был создан с помощью редактора полей (Fields Editor). Если редактор полей для создания TFields для полей таблицы не используется, получить доступ к полям можно с помощью метода FieldByName или свойства Fields, оба они являются членами компонентов TTable или TQuery. В случае ссылки на BLOB-поле таблицы с помощью одного из приведенных членов, перед использованием метода Assign указатель на поле должен быть прежде приведен к типу объекта TBLOBField. Для примера:
Изображение, хранящееся в BLOB-поле, может быть скопировано непосредственно в отдельный TBitmap объект. Ниже приведен пример, демонстрирующий создание объекта TBitmap и сохранения в нем изображения из BLOB-поля.
Многие мои друзья и знакомые часто спрашивают меня о том, как устроен мой сайт, сколько у меня таблиц в базе данных, как я храню данные и по каким полям веду поиск. Я, конечно, не выдаю все свои государственные тайны, но всегда понимаю причину таких вопросов и пытаюсь помочь людям построить быструю и надежную базу данных - т.е. тщательно продумать структуру БД таким образом, чтобы при увеличении нагрузки или объема таблиц динамический веб-сайт не превратился в тормозное усмертие.
А ведь многие новички (веб-строители) даже не догадываются о том, что крупные динамические сайты тормозят вовсе не из-за нагрузки скриптов на процессор, а в основном из-за неоптимизированного или дохленького MySQL-сервера. При этом во многом все зависит от того, как устроена ваша база данных.
Итак, начнем ликбез. Сразу всем вопрос: что делает MySQL во время записи в таблицы типа INSERT или UPDATE? Правильно - БЛОКИРУЕТ ТАБЛИЦЫ и пишет в них данные. Скорость записи и поиска может быть достаточно низкой, поэтому статус таблиц запрещает другим процессам считывать из них данные до окончания операции записи или обновления и снятия блокировки. При этом может получиться так, что во время записи единственного поля в длинные таблицы, ваш MySQL-сервер надолго заблокирует доступ к таблице остальным скриптам.
Например, вы создали таблицу новостей такого типа:
ID - номер, первичный ключ TEMA - тема новости MESS - сообщение, сама новость VIEWS - количество просмотров
При каждом обращении к новостям, скрипт будет выводить саму новость, а потом увеличивать поле VIEWS запросом UPDATE table 'NEWS' set VIEWS=VIEWS+1 where id=ID. При этом количество апдейтов будет довольно высоким. При высокой посещаемости веб-ресурса или при "нападении" на сайт поискового робота (эти ребята страдают многопоточностью и могут запросто повесить ваш сайт своими запросами) несколько одновременных процессов станут пытаться сделать UPDATE и SELECT. При каждом UPDATE таблица будет блокироваться (на это уходит время) и все остальные процессы будут ждать завершения операции. А если таблица достаточно большая? Например, несколько тысяч записей. Ежу понятно, что построится очередь из нескольких десятков скриптов, ожидающих ответа MySQL-сервера. Каждый будет жрать память и держать остальные процессы. В итоге все у вас зависнет и переглючит. Выход: делать вместо одной таблицы несколько. Советую разделять поля по типу их использования. Одну таблицу - только для вывода и редких обновлений или вставок. Другую - для частых обновлений, но редкого вывода. Например, значения счетчика обращений держать отдельно в таблицу вида:
ID - номер, первичный ключ VIEWS - количество просмотров
Сами новости лучше держать в другой таблице, где нет поля VIEWS. При этом таблица с новостями будет тяжелой (много текста, полей, индексов), а таблица COUNT (счетчик) будет очень легкой и быстрой. Таблица NEWS будет кешироваться и выводиться очень быстро при любых объемах, а таблица COUNT будет быстро обновляться из-за того, что она очень легкая (всего два целочисленных поля). Разделение данных по нескольким таблицам существенно ускоряет работу MySQL-сервера. Гораздо быстрее работают несколько мелких запросов по каждой таблице, чем один длинный запрос по одной или нескольким таблицам. Имейте это в виду, чтобы спать спокойно.
Дальше - круче. Чтобы не блокировать лишний раз свои таблицы используйте при вставках директиву DELAYED. Пример: INSERT DELAYED into STAT (ID,IP,UTIME) values (null,$ip,NOW()). Он позволяет серверу ответвлять поток в режиме ожидания, а саму вставку производить тогда, когда сервер освободится от других запросов или поступит следующий аналогичный INSERT DELAYED. Обычно отложенный метод подходит для любых операций с кумулятивными таблицами (когда в основном идут INSERTы, а данные копятся, а не модифицируются), при которых не особо важно когда именно подействуют изменения - мгновенно или через несколько секунд, минут. Например, если хотите собирать IPадреса своих посетителей, УРЛы, по которым они ходят или страницы, откуда пришли, время. При добавлении с задержкой скрипт отработает почти мгновенно, еще до выполнения операции.
Операция UPDATE идет в три этапа: поиск того, что будете менять, затем запись данных, обновление индексов. При этом, чем больше таблица, тем дольше поиск. Если есть индексы, то операция кешируется и выполняется достаточно быстро. Но сам процесс очень емкий. И только дурак не догонит, что большая таблица со множеством индексов и записей, будет тормозить при UPDATE. INSERT же выполняется одним залпом, очень быстро. Поэтому обычно используют аддитивные записи (вставками INSERT) во временные таблицы, потом блокируют основные талицы, суммируют обновления, и плюют их в основную таблицу. Получается, что в основном, главные таблицы работают только в режиме вывода, а обновления идут гораздо реже и быстрее. Например, можно копить данные о загрузках новостей во временной таблице, а по крону или иным образом обновлять счетчик каждые 10 минут (или реже). Это ускорит работу сервера.
При запросах SELECT * FROM таблица скрипт получит все поля данной таблицы. А нужно ли это? Использование * ведет к лишнему расходу ресурсов. Гораздо эффективнее использовать точные названия полей, которые нужны скрипту. Например: SELECT id,name FROM таблица. При таком запросе передача займет меньше времени и понадобится меньше ресурсов. Старайтесь ограничивать вывод при помощи директивы LIMIT. Это также ускоряет вывод.
Поиск по БД идет быстрее если вместо LIKE '%слово%', ставить 'слово%'. Операции с шаблонами регулярных выражений кешируются только в том случае, если в начале отсутствует символ %. Поэтому при построении поисковых запросов с LIKE избегайте начинающих символов %.
При построении таблиц для наиболее используемых полей (при поиске, сортировке и т.д.) обязательно создавайте индексы. Без индексов таблицы будут сильно тормозить. Индексы служат для кеширования и позволяют существенно ускорить вывод данных из таблиц. При этом таблицы будут занимать больше места на диске и в памяти. Но это в наше время не проблема.
Используйте надлежащий тип полей для своих записей. Тип TINYINT занимает 1 байт - самый быстрый. Таблицы с MEDIUMINT быстрее таблиц с INT. Если ставить полям свойство NOT NULL, то в целом их работа будет быстрее. VARCHAR медленее CHAR, поэтому таблицы переменной длины (где есть тип VARCHAR или TEXT) занимают меньше дискового пространства, но работают медленнее.
По своему опыту скажу, что для большинства сайтов подходят изложенные советы по работе с MySQL. Чтобы еще больше ускорить свой сервер, советую частоиспользуемые операции проводить по крону выделенными процессами и писать данные в различные файлы. Например, раз в 20 минут запускать скрипт, который будет создавать файл с новостями. Или например, генерить файл с новостями при их добавлениях или обновлениях. Таким образом, вы экономите на каждом обращении к БД. Интерактивность при этом не теряется, а производительность увеличивается во много раз. Особенно, повторяю, при высокой посещаемости ресурса. Старайтесь отделить интерактивные операции от фоновых. Например, на ПротоПлексе работает один интерактивный движок, но в фоне по заданиям трудятся с десяток различных роботов, которые генерируют часто вызываемые страницы, рассылают письма и т.д. Крупный сайт - это не только то, что вы видите, но и бек-енд (обратная сторона). В фоновом режиме можно быстро и эффективно готовить контент, освобождая основной движок от лишней работы.
В общем, основы должны быть всем понятны. Дробите все на мелочи, будь то запросы, таблицы или операции. Структура БД должна быть такой, чтобы не выполнялось ничего лишнего. Регулярно проводите OPTIMIZE на таблицах с переменной длиной, особенно, если в них идут удаления записей. Тестируйте свои запросы на скорость, упрощайте их.
Оптоволоконный (он же волоконно-оптический) кабель – это принципиально иной тип кабеля по сравнению с рассмотренными двумя типами электрического или медного кабеля. Информация по нему передается не электрическим сигналом, а световым. Главный его элемент – это прозрачное стекловолокно, по которому свет проходит на огромные расстояния (до десятков километров) с незначительным ослаблением.
Рис. 2.4. Структура оптоволоконного кабеля
Структура оптоволоконного кабеля очень проста и похожа на структуру коаксиального электрического кабеля (рис. 2.4). Только вместо центрального медного провода здесь используется тонкое (диаметром около 1 – 10 мкм) стекловолокно, а вместо внутренней изоляции – стеклянная или пластиковая оболочка, не позволяющая свету выходить за пределы стекловолокна. В данном случае речь идет о режиме так называемого полного внутреннего отражения света от границы двух веществ с разными коэффициентами преломления (у стеклянной оболочки коэффициент преломления значительно ниже, чем у центрального волокна). Металлическая оплетка кабеля обычно отсутствует, так как экранирование от внешних электромагнитных помех здесь не требуется. Однако иногда ее все-таки применяют для механической защиты от окружающей среды (такой кабель иногда называют броневым, он может объединять под одной оболочкой несколько оптоволоконных кабелей).
Оптоволоконный кабель обладает исключительными характеристиками по помехозащищенности и секретности передаваемой информации. Никакие внешние электромагнитные помехи в принципе не способны исказить световой сигнал, а сам сигнал не порождает внешних электромагнитных излучений. Подключиться к этому типу кабеля для несанкционированного прослушивания сети практически невозможно, так как при этом нарушается целостность кабеля. Теоретически возможная полоса пропускания такого кабеля достигает величины 1012 Гц, то есть 1000 ГГц, что несравнимо выше, чем у электрических кабелей. Стоимость оптоволоконного кабеля постоянно снижается и сейчас примерно равна стоимости тонкого коаксиального кабеля.
Типичная величина затухания сигнала в оптоволоконных кабелях на частотах, используемых в локальных сетях, составляет от 5 до 20 дБ/км, что примерно соответствует показателям электрических кабелей на низких частотах. Но в случае оптоволоконного кабеля при росте частоты передаваемого сигнала затухание увеличивается очень незначительно, и на больших частотах (особенно свыше 200 МГц) его преимущества перед электрическим кабелем неоспоримы, у него просто нет конкурентов.
Однако оптоволоконный кабель имеет и некоторые недостатки.
Самый главный из них – высокая сложность монтажа (при установке разъемов необходима микронная точность, от точности скола стекловолокна и степени его полировки сильно зависит затухание в разъеме). Для установки разъемов применяют сварку или склеивание с помощью специального геля, имеющего такой же коэффициент преломления света, что и стекловолокно. В любом случае для этого нужна высокая квалификация персонала и специальные инструменты. Поэтому чаще всего оптоволоконный кабель продается в виде заранее нарезанных кусков разной длины, на обоих концах которых уже установлены разъемы нужного типа. Следует помнить, что некачественная установка разъема резко снижает допустимую длину кабеля, определяемую затуханием.
Также надо помнить, что использование оптоволоконного кабеля требует специальных оптических приемников и передатчиков, преобразующих световые сигналы в электрические и обратно, что порой существенно увеличивает стоимость сети в целом.
Оптоволоконные кабели допускают разветвление сигналов (для этого производятся специальные пассивные разветвители (couplers) на 2—8 каналов), но, как правило, их используют для передачи данных только в одном направлении между одним передатчиком и одним приемником. Ведь любое разветвление неизбежно сильно ослабляет световой сигнал, и если разветвлений будет много, то свет может просто не дойти до конца сети. Кроме того, в разветвителе есть и внутренние потери, так что суммарная мощность сигнала на выходе меньше входной мощности.
Оптоволоконный кабель менее прочен и гибок, чем электрический. Типичная величина допустимого радиуса изгиба составляет около 10 – 20 см, при меньших радиусах изгиба центральное волокно может сломаться. Плохо переносит кабель и механическое растяжение, а также раздавливающие воздействия.
Чувствителен оптоволоконный кабель и к ионизирующим излучениям, из-за которых снижается прозрачность стекловолокна, то есть увеличивается затухание сигнала. Резкие перепады температуры также негативно сказываются на нем, стекловолокно может треснуть.
Применяют оптоволоконный кабель только в сетях с топологией звезда и кольцо. Никаких проблем согласования и заземления в данном случае не существует. Кабель обеспечивает идеальную гальваническую развязку компьютеров сети. В будущем этот тип кабеля, вероятно, вытеснит электрические кабели или, во всяком случае, сильно потеснит их. Запасы меди на планете истощаются, а сырья для производства стекла более чем достаточно.
Существуют два различных типа оптоволоконного кабеля:
* многомодовый или мультимодовый кабель, более дешевый, но менее качественный;
* одномодовый кабель, более дорогой, но имеет лучшие характеристики по сравнению с первым.
Суть различия между этими двумя типами сводится к разным режимам прохождения световых лучей в кабеле.
Распространение света в одномодовом кабеле
Рис. 2.5. Распространение света в одномодовом кабеле
В одномодовом кабеле практически все лучи проходят один и тот же путь, в результате чего они достигают приемника одновременно, и форма сигнала почти не искажается (рис. 2.5). Одномодовый кабель имеет диаметр центрального волокна около 1,3 мкм и передает свет только с такой же длиной волны (1,3 мкм). Дисперсия и потери сигнала при этом очень незначительны, что позволяет передавать сигналы на значительно большее расстояние, чем в случае применения многомодового кабеля. Для одномодового кабеля применяются лазерные приемопередатчики, использующие свет исключительно с требуемой длиной волны. Такие приемопередатчики пока еще сравнительно дороги и не долговечны. Однако в перспективе одномодовый кабель должен стать основным типом благодаря своим прекрасным характеристикам. К тому же лазеры имеют большее быстродействие, чем обычные светодиоды. Затухание сигнала в одномодовом кабеле составляет около 5 дБ/км и может быть даже снижено до 1 дБ/км.
Распространение света в многомодовом кабеле
Рис. 2.6. Распространение света в многомодовом кабеле
В многомодовом кабеле траектории световых лучей имеют заметный разброс, в результате чего форма сигнала на приемном конце кабеля искажается (рис. 2.6). Центральное волокно имеет диаметр 62,5 мкм, а диаметр внешней оболочки 125 мкм (это иногда обозначается как 62,5/125). Для передачи используется обычный (не лазерный) светодиод, что снижает стоимость и увеличивает срок службы приемопередатчиков по сравнению с одномодовым кабелем. Длина волны света в многомодовом кабеле равна 0,85 мкм, при этом наблюдается разброс длин волн около 30 – 50 нм. Допустимая длина кабеля составляет 2 – 5 км. Многомодовый кабель – это основной тип оптоволоконного кабеля в настоящее время, так как он дешевле и доступнее. Затухание в многомодовом кабеле больше, чем в одномодовом и составляет 5 – 20 дБ/км.
Типичная величина задержки для наиболее распространенных кабелей составляет около 4—5 нс/м, что близко к величине задержки в электрических кабелях.
Оптоволоконные кабели, как и электрические, выпускаются в исполнении plenum и non-plenum.
Такие типы данных, как int, float, char и long, являются неотъемлемой частью C/C++ и вам не нужно писать никакого кода, чтобы сообщить компилятору о том, что означают эти слова. C/C++ позволяет вам также объ-являть свои собственные, специальные типы данных. В следующем разделе вы узнаете, как объявлять структуры, которые можно отнести к специальным типам данных.
Как вы уже знаете, переменная в C/C++ объявляется следующим образом:
В приведенном операторе iMyVariable объявлена как целая переменная. А вот объявление переменной типа char:
Напишите следующий исходный код:
В коде, который вы написали, имеются два оператора #include:
Файл iostream.h включен в код, поскольку в main(void) используется cout. Файл string.h включается потому, что в main(void) используется функция strcpy() (объявленная в файле string.h). Затем вы объявляете структуру:
Обратите внимание на синтаксис объявления структуры. Оно начинается с ключевого слова struct, за которым следует имя типа-структуры. В этой программе типу структуры присвоено имя MYSTRUCTURE. Затем следует собственно определение структуры, заключенное в фигурные скобки. Не забудьте поставить точку с запятой после закрывающей фигурной скобки. Теперь посмотрите на код внутри фигурных скобок:
Это означает, что MYSTRUCTURE состоит из строки с именем sName и целого с именем iAge, sName и iAge называются элементами данных структуры; Вы объявили их "Внутри" cтруктуры MYSTRUCTURE. Код в main(void) объявляет переменную с именем MyStructure типа MYSTRUCTURE:
Вспомните, что в объявляли переменную iNum1 следующим образом:
Когда вы объявляете MyStructure , которая будет структурой типа MYSTRUCTURE, рассматривайте переменную MyStructure аналогично переменной iNum1. MyStructure - это имя переменной, а ее типом является MYSTRUCTURE точно так же, как типом переменной iNum1 является int. (Обратите внимание, что по традиции имя структуры составлено из символов нижнего регистра или в нем смешаны символы нижнего и верхнего регистров, как, например, в имени MyStructure, но в имени типа структуры используются только символы верхнего регистра, как, например, в MYSTRUCTURE.)
Следующий оператор в main(void) копирует строку 'Andy' в элемент данных MyStructure.sName:
В этом операторе обращение к элементу данных sName записано как MyStructure.sName Следующий оператор присваивает значение 13 элементу данных iAge cтруктуры MyStructure: MyStructure.iAge - 13; Затем выполняется ряд операторов вывода cout:
Сложив все вместе, мы видим, что программа MyStruct выводит сообщение My name is Andy and I am 13 years old. (Меня зовут Andy и мне 13 лет)
В состав библиотеки MFC входит ряд классов, представляющих стандартные диалоговые панели. Эти классы позволяют легко реализовать такие часто используемые операции, как открытие и сохранение файла, выбор цвета, выбор шрифта и т.д. Все эти классы наследуются от CCommonDialog, который в свою очередь является производным по отношению к базовому классу CDialog.
Приведем классы стандартных диалоговых панелей и их назначение:
CColorDialog - Панель для выбора цвета
CFileDialog - Панель выбора файлов для открытия и сохранения на диске
CFindReplaceDialog - Панель для выполнения операции поиска и замены
CFontDialog - Панель для выбора шрифта
CPrintDialog - Панель для вывода документа на печать
CPageSetupDialog - Панель выбора формата документа
COleDialog - Панель для управления технологией OLE
Классы, управляющие стандартными диалоговыми панелями, определены в файле afxdlgs.h. Поэтому при использовании этих классов в приложении необходимо включить этот файл в исходный текст при помощи директивы #include.
Панель выбора цвета (класс CColorDialog)
Чтобы отобразить на экране стандартную диалоговую панель выбора цвета, надо создать объект класса CColorDialog, а затем вызвать метод DoModal. При создании объекта класса СColorDialog используется следующий конструктор:
Все параметры конструктора необязательны, однако в некоторых случаях использование этих параметров может помочь.
Первый параметр clrInit позволяет указать цвет, выбранный по умолчанию сразу после открытия диалоговой панели. Если параметр не будет указан, в качестве цвета, выбранного по умолчанию, будет использоваться черный цвет.
Параметр dwFlags содержит набор флагов, управляющих диалоговой панелью выбора цвета. При помощи него блокировать или разрешать работу некоторых элементов управления диалоговой панели выбора цвета. Если при создании объекта класса CColorDialog не указать параметр dwFlags, тем не менее можно выполнить настройку диалоговой панели, обратившись непосредственно к элементу m_cc данного класса. Параметр dwFlags, указанный в конструкторе, используется для инициализации m_cc. Изменения в элемент m_cc должны быть внесены до того, как панель будет отображаться на экране.
Последний параметр pParentWnd можно использовать, чтобы указать родительское окно диалоговой панели.
Методы класса CСolorDialog
Чтобы вывести диалоговую панель выбора цвета на экран, необходимо использовать метод DoModal. После отображения панели на экране пользователь может выбрать из нее цвет и нажать кнопки OK или Cancel для подтверждения выбора цвета или отказа от него. Когда диалоговая панель закрывается, метод DoModal возвращается значения IDOK и IDCANCEL, в зависимости от того, какую кнопку нажал пользователь:
На экране появится стандартная диалоговая панель выбора цвета Color. В верхней половине диалоговой панели расположены 48 прямоугольников, имеющих различные цвета. Они представляют так называемые основные цвета (Basic colors). Можно выбрать один из этих цветов и нажать кнопку OK. После того, как диалоговая панель закрыта (метод DoModal завершил свою работу), можно воспользоваться методами класса CColorDialog, чтобы узнать цвета, выбранные пользователем.
Для определения цвета, выбранного пользователем, можно обратиться к методу GetColor класса CColorDialog. Данный метод возвращает значение COLORREF, соответствующее выбранному цвету.
Если пользователю недостаточно основных цветов, представленных в диалоговой панели Color, он может выбрать до 16 дополнительных цветов. Для этого он должен нажать кнопку DefineCustom Colors. Диалоговая панель изменит свой внешний вид - появятся дополнительные органы управления, позволяющие выбрать любой из 16 777 216 цветов. Когда цвет выбран, нужно нажать кнопку Add Custom Colors. Выбранный цвет будет добавлен к дополнительным цветам (Custom colors) - один из свободных прямоугольников окрасится соответствующим цветом.
При помощи метода GetSavedCustomColors класса CColorDialog можно определить дополнительные цвета, выбранные пользователем в диалоговой панели Color. Этот метод возвращает указатель на массив из 16 элементов типа COLORREF. Каждый элемент массива описывает один дополнительный цвет.
Когда диалоговая панель Color отображается приложением первый раз, все прямоугольники, отображающие дополнительные цвета, имеют белый цвет. Дополнительные цвета, выбранные пользователем, сохраняются во время работы приложения. После перезапуска приложения дополнительные цвета сбрасываются.
Панель выбора файлов (класс CFileDialog)
Среди стандартных диалоговых панелей, для которых в библиотеке MFC создан специальный класс, есть панели для работы с файловой системой - Open и Save As. Диалоговая панель Open позволяет выбрать один или несколько файлов и открыть их для дальнейшего использования. Диалоговая панель Save As позволяет выбрать имя файла для записи в него документа.
Для управления диалоговыми панелями Open и Save As предназначен один класс CFileDialog. Рассмотрим конструктор класса CFileDialog более подробно:
Объекты класса CFileDialog представляют диалоговые панели Open или Save As в зависимости от параметра bOpenFileDialog. Если параметр bOpenFileDialog содержит значение TRUE, то создается объект, управляющий диалоговой панелью Open, а если FALSE - диалоговой панелью Save As.
Параметр bOpenFileDialog является единственным обязательным параметром, который необходимо указать. Остальные параметры конструктора класса CFileDialog задают различные режимы работы панели и могут не указываться.
Чтобы создать объект класса CFileDialog , представляющий диалоговую панель для открытия файлов (mFileOpen), и объект, представляющий диалоговую панель для сохранения файлов (mFileSaveAs), можно воспользоваться следующими вызовами конструктора класса:
Во многих случаях имена файлов, которые нужно открыть или закрыть, имеют определенное расширение. Параметр lpszDefExt позволяет задать расширение файлов, используемое по умолчанию. То есть, если пользователь при определении имени файла не укажет расширение, имени файла автоматически присваивается расширение, принятое по умолчанию. Если при определении свойств диалоговой панели программист присвоит параметру lpszDefExt значение NULL, то расширение файлов должно задаваться пользователем явно.
В некоторых случаях требуется, чтобы диалоговые панели отображались с уже выбранным именем файла. Чтобы указать имя файла, используемое по умолчанию, применяется параметр lpszFileName. Если параметр lpszFileName имеет значение NULL, данная возможность не реализуется.
С помощью флага dwFlags можно изменить внешний вид и некоторые другие характеристики стандартных диалоговых панелей класса CFileDialog. В него можно записать комбинацию флагов, управляющих различными характеристиками этих панелей. Например, флаг OFN_HIDEREADONLY означает, что из диалоговой панели удаляется переключатель "Read Only", а флаг OFN_OVERWRITEPROMPT (используемый для панели Save As) - что необходимо выводить диалоговую панель с предупреждением, если пользователь выбирает для сохранения имя уже существующего файла.
Диалоговые панели выбора файлов обычно имеют список так называемых фильтров, включающих названия типов файлов и расширения имен файлов данного типа. Выбрав фильтр, пользователь указывает, что он желает работать только с файлами определенного типа, имеющими соответствующее расширение. Файлы с другими расширениями в диалоговых панелях не отображаются.
Список фильтров можно указать через параметр lpszFilter. Одновременно можно указать несколько фильтров. Каждый фильтр задается двумя строками - строкой, содержащей имя фильтра, и строкой, в которой перечислены соответствующие ему расширения имен файлов. Если одному типу соответствует несколько расширений, они разделяются символом ;. Строка, содержащая имя фильтра, отделяется от строки с расширениями файлов символом |. Если используется несколько фильтров, то они также отделяются друг от друга символом |. Например, в качестве строки, задающей фильтры, можно использовать строку вида:
Диалоговые панели, представленные объектами класса CFileDialog, могут иметь или не иметь родительского окна. Чтобы указать родительское окно, нужно передать конструктору CFileDialog указатель на него через параметр pParentWnd.
Методы класса CFileDialog
Создание объекта класса CFileDialog еще не вызывает отображения соответствующей диалоговой панели. Для этого необходимо воспользоваться методом DoModal класса CFileDialog.При вызове метода DoModal для ранее созданного объекта класса CFileDialog на экране открывается соответствующая диалоговая панель. После того, как пользователь завершает работу с диалоговой панелью, метод DoModal вернет значение IDOK или IDCANCEL в случае успешного завершения и нуль - в случае возникновения ошибок:
После того, как пользователь закроет диалоговую панель и метод DoModal вернет управление, можно воспользоваться другими методами класса CFileDialog , чтобы определить имена выбранных файлов:
GetPathName - Определяет полный путь файла
GetFileName - Определяет имя выбранного файла
GetFileExt - Определяет расширение имени выбранного файла
GetFileTitle - Позволяет определить заголовок выбранного файла
GetNextPathName - Если диалоговая панель позволяет выбрать сразу несколько файлов, то этот метод можно использовать для определения полного пути следующего из выбранных файлов
GetReadOnlyPref - Позволяет узнать состояние атрибута "только для чтения" (read-only) выбранного файла
GetStartPosition - Возвращает положение первого элемента из списка имен файлов
Наиболее важный метод - GetPathName. Он получает полный путь файла, выбранного из диалоговых панелей Open или Save As. Если диалоговая панель позволяет выбрать сразу несколько файлов, тогда метод GetPathName возвращает массив строк, состоящий из нескольких строк, заканчивающихся двоичным нулем. Первая из данных строк содержит путь к каталогу, в котором расположены выбранные файлы, остальные строки содержат имена выбранных файлов. Выделение строки, содержащей путь к каталогу, проблем не вызывает, а чтобы получить имена выбранных файлов, необходимо воспользоваться методами GetStartPosition и GetNextPathName.
[pagebreak]
Метод GetStartPosition возвращает значение типа POSITION. Оно предназначено для передачи методу GetNextPathName и получения очередного имени выбранного файла. Если пользователь не выбрал ни одного файла, метод GetStartPosition возвращает значение NULL. Значение, полученное этим методом, следует записать во временную переменную типа POSITION и передать ссылку на нее методу GetNextPathName. Метод GetNextPathName вернет полный путь первого из выбранных в диалоговой панели файлов и изменит значение переменной pos, переданной методу по ссылке. Новое значение pos можно использовать для последующих вызовов метода GetNextPathName и получения путей всех остальных выбранных файлов. Когда метод GetNextPathName вернет имена всех выбранных файлов, в переменную pos записывается значение NULL.
В панелях Open и Save As имеется переключатель "ReadOnly". По умолчанию этот преключатель не отображается. Если есть необходимость воспользоваться этим переключателем, то нужно отказаться от использования флага OFN_HIDEREADONLY.
Метод GetReadOnlyPref позволяет определить положение переключателя "ReadOnly". Если переключатель включен, то метод GetReadOnlyPref возвращает ненулевое значение. В противном случае GetReadOnlyPref возвращает нуль.
Панель выбора шрифта (класс CFontDialog)
Стандартная диалоговая панель Font предназначена для выбора шрифта. Эта панель отображает список шрифтов, установленных в системе, и позволяет выбрать название шрифта, его начертание и другие параметры.
Для управления диалоговой панелью Font в библиотеку классов MFC включен класс CFontDialog. Методы этого класса можно использовать для отображения панели Font и определения характеристик шрифта, выбранного пользователем. Конструктор класса CFontDialog:
Все параметры конструктора являются необязательными. Настройка стандартной панели выбора шрифта, которая выполняется конструктором класса CFontDialog по умолчанию, удовлетворяет большинству пользователей.
Параметр lplfInitial является указателем на структуру LOGFONT, описывающую логический шрифт. Если этот параметр используется, то в диалоговой панели по умолчанию будет выбран шрифт, наиболее соответствующий шрифту, описанному в структуре LOGFONT.
Параметр dwFlags задает набор флагов, управляющий различными режимами работы панели. Например, флаг CF_EFFECTS позволяет пользователю создавать подчеркнутые и перечеркнутые буквы, определять цвет букв, а флаг CF_SCREENFONTS - разрешает выбирать только экранные шрифты.
Через параметр pdcPrinter можно передать конструктору контекст отображения принтера, шрифты которого будут представлены в диалоговой панели Font. Данный параметр используется только в том случае, если в параметре dwFlags указаны флаги CF_PRINTERFONTS или CF_BOTH.
Через параметр pParentWnd можно указать родительское окно для диалоговой панели Font.
Методы класса CFontDialog
Для отображения диалоговой панели Font предназначен виртуальный метод DoModal. Если пользователь выбрал шрифт и нажал кнопку OK, метод DoModal возвращает идентификатор IDOK, если пользователь отменил выбор шрифта, метод DoModal возвращает идентификатор IDCANCEL:
Остальные методы класса предназначены для определения характеристик выбранного пользователем шрифта.
Метод GetCurrentFont позволяет сразу определить все характеристики выбранного шрифта, записав их в структуру LOGFONT.
Остальные методы класса позволяют определить только отдельные характеристики выбранного шрифта:
GetFaceName - Возвращает имя выбранного шрифта
GetStyleName - Возвращает имя стиля выбранного шрифта
GetSize - Возвращает размер выбранного шрифта
GetColor - Возвращает цвет выбранного шрифта
GetWeight - Возвращает плотность выбранного шрифта
IsStrikeOut - Определяет, является ли шрифт выделенным перечеркнутой линией
IsUnderline - Определяет, является ли шрифт выделенным подчеркиванием
IsBold - Определяет, является ли шрифт жирным
IsItalic - Определяет, является ли шрифт наклонным
Панель для вывода документов на печать (класс CPrintDialog)
Класс CPrintDialog можно использовать для создания двух видов диалоговых панелей, предназначенных для печати документов и выбора форматов документов. Кроме класса CPrintDialog можно также использовать класс CPageSetupDialog. Он позволяет создать диалоговую панель для выбора формата документа, имеющую несколько иной вид.
В приложениях, подготовленных с использованием средств MFC AppWizard и построенные по модели документ-облик, по умолчанию встроена возможность вывода редактируемого документа на печать.
В меню File такого приложения находятся три строки (Print, Print Preview и Print Setup), которые управляют процессом печати документов, подготовленных в приложении. Чтобы распечатать документ, достаточно выбрать из меню File строку Print. На экране появится диалоговая панель Print. В ней можно выбрать печатающее устройство для печати документов (группа Name), указать, будет печататься весь документ либо его часть (группа Print range), а также сколько копий документа будет напечатано (группа Copies). Также можно настроить различные характеристики печатающего устройства, если нажать кнопку Properties в группе Printer.
Если требуется определить только печатающее устройство и формат документа, из меню File следует выбрать строку Printer Setup. В группе Printer можно указать печатающее устройство и настроить его соответствующим образом. Группа Paper задает формат бумаги и режим подачи бумаги в печатающее устройство. Группа Orientation включает только один переключатель, определяющий ориентацию бумаги. Он принимает положение Portrait для вертикальной ориентации изображения на бумаге (режим "портрет") или Landscape для горизонтальной ориентации изоборажения на бумаге (режим "ландшафт").
Строка Print Preview меню File выбирается для предварительного просмотра документа перед печатью. При этом главное окно приложения изменит свой внешний вид и можно будет просмотреть, как будет выглядеть документ после печати.
Если не требуется выполнять специфическую обработку документа перед печатью, то вряд ли понадобится самостоятельное добавление программного кода, отвечающего за процесс печати. Просто следует отметить, что процедура создания панелей, связанных с печатью документа, практически ничем не отличается от создания выше описанных стандартных диалоговых панелей.
Панель для выполнения поиска и замены (класс CFindReplaceDialog)
Класс CFindReplaceDialog предназначен для управления диалоговыми окнами Find и Replace. Диалоговая панель Find используется для поиска известных строк в документе приложения, а панель Replace позволяет замену одной строки на другую.
Важным отличием диалоговых панелей Find и Replace от других стандартных диалоговых панелей является то, что они представляют собой немодальные диалоговые панели. Поэтому процесс создания этих панелей значительно отличается от процесса создания стандартных панелей для выбора цвета, шрифта и имен файла.
Проблемы соединения волоконных световодов приобрели особую актуальность при разработке технологии их промышленного применения. Выбор способа сращивания зависит от условий применения волоконной оптики.
Очевидно, что значительные преимущества при использовании волоконно-оптических технологий в телекоммуникационной отрасли, связанные с улучшением целого ряда технико-экономических показателей (возрастанием скорости передачи информации, увеличением длины регенерационного участка, уменьшением массогабаритных характеристик кабелей, экономией цветных металлов и др.), предопределят в будущем широкое внедрение волоконной оптики при построении линий связи различных уровней. Однако необходимо было разработать методики сращивания волоконных световодов, обеспечивающие высокие качественные и вместе с тем достаточно технологичные и доступные показатели, чтобы сделать возможным применение этих световодов не только в стационарных, но и в полевых условиях.
Строительная длина волоконно-оптического кабеля на практике устанавливается, исходя из ряда факторов. Прокладка больших длин кабеля неудобна вследствие необходимости сматывания с барабана и манипуляций с кабелем как во время прокладки в полевых условиях (при пересечении других подземных коммуникаций), так и в городских условиях (при прокладке в кабельную канализацию). Прокладывая кабель с помощью кабелеукладочной техники, также возникают неудобства, связанные с манипуляциями большими длинами, если для погрузочно-разгрузочных работ приходится использовать специализированную технику. Особенно остро стоит проблема манипуляции строительными длинами с большой удельной массой при прокладке глубоководных морских кабелей и кабелей для прибрежной зоны. Из-за необходимости инсталляции кабелей максимально возможной длины для их транспортировки по суше используются спаренные железнодорожные платформы, на которых кабели выкладываются в форме "8", а не на кабельные барабаны. Таким образом кабель транспортируется по суше до погрузки на судно.
Для соединения оптических волокон разработаны два способа соединений: разъемные и неразъемные. Неразъемные соединения оптических волокон осуществляются методом сварки, методом склеивания, а также с помощью механических соединителей. Для создания разъемных соединений оптических волокон используются оптические коннекторы.
Соединения оптических волокон с помощью сварки
Соединение оптических волокон с помощью сварки является сегодня наиболее распространенным методом получения неразъемных соединений. Благодаря в достаточной мере совершенной технологии этот метод позволяет получать качественные соединения с низкими показателями вносимых потерь (порядка 0,1-0,15 дБ), что обуславливает его применение на линиях связи, где этот показатель входит в приоритетные - магистральные, зоновые и другие - высокоскоростные ВОЛС.
Сваривание оптических волокон предусматривает оплавление концов волоконных световодов путем помещения их в поле мощного источника тепловой энергии, как, например, поле электрического разряда, пламя газовой горелки, зона мощного лазерного излучения.
Каждый из перечисленных методов имеет свои достоинства и недостатки. Достоинством метода сварки с помощью лазера можно считать возможность получения чистых соединений из-за отсутствия в них сторонних примесей, и, как следствие, достаточно малых вносимых потерь (0,1 дБ и менее). Как правило, в качестве источника лазерного излучения высокой мощности (до 5 Вт) используются газовые лазеры на СО2.
К достоинствам метода сварки с помощью газовой горелки следует также отнести возможность получения соединений оптических волокон, отличающихся высокой прочностью мест сростков. В качестве источника пламени используют смесь пропана с кислородом или соединение кислорода, хлора и водорода. Этот метод распространен по большей части для сварки многомодовых оптических волокон.
Основным достоинством сварки в поле электрического разряда является быстрота и технологичность. Этот метод в настоящее время приобрел наибольшую популярность для сварки одномодовых световодов.
Аппараты для сварки оптических волокон можно классифицировать следующим образом: по способу юстировки свариваемых концов оптических волокон (в зависимости от геометрических размеров сердцевин или от потерь мощности светового сигнала, распространяющегося через место сварки); по способу проведения операций (ручные или автоматические); по типу устройства контроля (микроскоп, монитор на жидких кристаллах); по количеству оптических волокон, которые могут быть сварены одновременно (одно- и многоволоконные).
При сварке оптических волокон в поле электрического разряда можно выделить такие технологические этапы:
* подготовка торцевых поверхностей соединяемых оптических волокон;
* надевание защитной термоусаживаемой гильзы на одно из соединяемых волокон;
* установка подготовленных концов оптических волокон в направляющие системы сварочного аппарата;
* юстировка свариваемых оптических волокон;
* предварительное оплавление торцов оптических волокон (fire cleaning) с целью ликвидации микронеровностей, возникающих в
* процессе скалывания;
* непосредственное сваривание оптических волокон;
* предварительная оценка качества сварки;
* защита места сварки с помощью термоусаживаемой гильзы;
* окончательная оценка качества сварки с помощью рефлектометра.
Существует два способа юстировки. Первый базируется на выравнивании сердцевин свариваемых оптических волокон по их геометрическим размерам (Profile Alignment System PAS) с помощью боковой подсветки концов свариваемых волокон.
Второй способ основан на выравнивании сердцевин оптических волокон по принципу минимизации потерь тестового светового сигнала, распространяющегося через место сварки.
Что касается активной юстировки, то известно три метода.
Первый заключается в использовании оптического излучателя и приемника на противоположных концах оптических волокон, подлежащих сварке. Информация от приемника передается персоналу, производящему сварку.
Второй метод сводится к использованию оптического передатчика на дальнем конце и детектора в точке соединения. Тестовый оптический сигнал выводится из соединяемого оптического волокна на небольшом (примерно 0,5 м) расстоянии от места сварки на изгибе и детектируется приемником, оборудованным измерителем оптической мощности.
Третий метод реализует LID (Local Injection and Detection) - процедуру юстировки, ограниченную исключительно местом соединения. В основу этого метода положено введение тестового оптического сигнала в сердцевину одного из соединяемых оптических волокон и поиск его в сердцевине второго соединяемого волокна путем изгиба.
Метод LID является наиболее эффективным, поскольку, в отличие от метода PAS, качество сварного соединения в большей мере зависит от сварочного аппарата, а не от индивидуального мастерства персонала. В современных сварочных аппаратах для управления процессами юстировки и сварки используются микропроцессоры, с помощью которых возможна оптимизация процесса сварки для получения минимальных (менее 0,1 дБ) потерь в местах соединений оптических волокон.
В процессе оплавления оптические волокна подаются одновременно для предотвращения укорачивания одного из них в месте сварки. Операции оплавления и сваривания, как правило, выполняются автоматически. В современных автоматических сварочных аппаратах для снятия механического напряжения в точке соединения оптических волокон предусмотрен режим прогревания места стыка по окончании процесса сварки. Такой режим называется "режимом релаксации".
Цикл плавления (длительность подачи и сила тока как для предварительного оплавления, так и для сварки и релаксации) для оптических волокон различных производителей и типов различны.
Некоторые сварочные аппараты, кроме рассмотренных выше способов контроля качества места сварки, используют еще и тест на растяжение во избежание нарушения соединения во время манипуляций при выкладке сростков в кассету, а также в дальнейшем, в процессе эксплуатации. Соединенное оптическое волокно прочно закреплено в направляющих платформах (которые используются при юстировке). Под контролем микропроцессора по завершении этапа сварки эти направляющие платформы расходятся в противоположные стороны, образуя строго нормированное продольное усилие на растяжение, приложенное к месту стыка. Считается, что стык, прошедший такое тестирование, более надежен и выполнен более качественно. При невозможности получения стыка, способного пройти этот тест, но удовлетворяющего по параметрам передачи, эту опцию можно отключить.
Особо следует отметить сварку ленточных элементов (ленточных волоконно-оптических кабелей, отличающихся большим количеством оптических волокон). Эту операцию можно проводить, только применяя полностью автоматический сварочный аппарат, с помощью которого можно соединить до 12 оптических волокон приблизительно за 3 минуты, причем средний уровень потерь составит около 0,1-0,15 дБ. Однако для сваривания ленточных элементов необходим опытный, хорошо подготовленный персонал.
Во время сварки оптические волокна размещаются с соответствующим смещением от оси электродов, что обеспечивает равномерное нагревание. До начала процесса сваривания и по его завершении проверяется смещение оптических волокон, состояние торцевых поверхностей, а также деформация.
При сваривании ленточных элементов необходимо, кроме основных процессов, рассмотренных ранее, провести еще три технологические операции: устранить расхождения торцов соединяемых оптических волокон, плавление всех волокон выполнить одновременно с одинаковой температурой, в процессе предварительной оценки измерить уровень вносимых потерь рефлектометром. Если оказалось, что результаты не отвечают требованиям, процесс сварки повторяют.
Как показывает практика, предварительная оценка качества сварных соединений оптических волокон, базирующаяся на методе РАС, может содержать погрешность в диапазоне 5-1000%, поэтому окончательный вывод о качестве сварного соединения стоит делать после измерений рефлектометром.
По мере совершенствования качества сварочного оборудования и технологии сварки возрастают возможности получения сварных соединений оптических волокон высокого качества. Потери на сварных соединениях зависят от нескольких факторов: опыта персонала, геометрических погрешностей свариваемых оптических волокон, а также от материалов, из которых изготовлены волокна. Особенно часто проблемы возникают при сварке оптических волокон различных производителей. Дело в том, что оптические волокна различных производителей изготавливаются с использованием принципиально отличающихся друг от друга технологических процессов. В результате материал оптических волокон - кварцевое стекло - не является идентичным в волокнах различного происхождения, несмотря на то, что параметры оптических волокон, указанные в спецификациях фирм-производителей, отличаются незначительно.
Факторами, определяющими свойства стекла, являются технология изготовления и качество материалов. Многочисленные исследования показали, что тысячные доли процента примесей в кварцевом стекле оказывают большее влияние, чем добавки в десятки процентов тех же компонентов к многокомпонентным стеклам.
Для сварки наибольшее влияние имеют следующие характеристики: плотность, коэффициент теплового расширения, показатель преломления, вязкость и механические характеристики. Эти параметры определяют оптические потери в местах сращивания и должны приниматься во внимание при использовании оптических волокон, произведенных по различным технологиям, в пределах одного элементарного кабельного участка ВОЛС. Особое внимание следует уделять идентификации оптических волокон в кабеле по типу, производителю и технологии изготовления.
Более совершенные аппараты для сварки оптических волокон содержат программы, оптимизирующие процесс сварки для оптических волокон различных типов и различных производителей, однако на практике нередки ситуации, когда, используя стандартные программы, невозможно получить качественную сварку. В этих случаях необходимо самостоятельно корректировать параметры процесса (время и ток, подаваемый на электроды) для достижения оптимальных результатов.
[pagebreak]
Наиболее часто сварка оптических волокон различных производителей производится при оконцовке оптических волокон пигтейлами, а также при ремонтно-восстановительных работах, если эксплуатационный запас кабеля израсходован, и приобретение полностью идентичного кабеля невозможно (к примеру, по причине снятия с производства оптического волокна такого типа, который использовался первоначально) или экономически нецелесообразно.
В общем виде величина потерь в местах сварных соединений может быть представлена как суммарная величина: Dобщ = Dор + Dдм + Dую + Dнм + Dрпп, где: Dобщ - суммарная величина потерь в сварке; Dор - потери из-за осевого рассогласования модовых полей равного диаметра; Dдм - потери из-за разницы диаметров модовых полей; Dую - потери от погрешности угловой юстировки осей оптических волокон; Dнм - потери, обусловленные не-круглостью модовых полей; Dрпп - потери из-за разницы показателей преломления.
Изучение параметров и характеристик различных одномодовых оптических волокон показывает, что разброс величины диаметра модового поля для l = 1310.1330 нм или l = 1500...1550 нм может составлять от 10,5 до 21,7% (9,2 0,5 мкм). Такое рассогласование приводит к появлению потерь от 0,05 дБ до 0,25 дБ (с положительным знаком, когда излучение проходит из волокна с большим диаметром в волокно с меньшим диаметром, и отрицательным - в противоположном направлении). Эти потери будут иметь место, даже если аппарат расположит соосно два волокна с разными диаметрами сердцевин, у которых эксцентриситет пренебрежительно мал. Обычно разброс величины модового поля оптического волокна не превышает 14%, таким образом, величина этой составляющей - не более 0,1 дБ.
Составляющая Dую практически не компенсируется современным сварочным оборудованием. Установлено, что углы между осями сердцевин 0,5°; 1°; 1,5°; 2° вызывают приращение потерь соответственно в 0,08; 0,34; 0,77 и 1,5 дБ. Таким образом, благодаря надлежащей подготовке торцов соединяемых оптических волокон при скалывании можно уменьшить потери - необходимо обеспечить наименьший (не более 0,5°) угол между плоскостями торцов оптических волокон. В этом случае величина потерь не превысит 0,08 дБ.
Составляющая Dнм учитывает влияние некруглости модового поля. По приблизительным оценкам она равна 0,05 дБ.
При соединении сваркой оптических волокон, имеющих неконцентричность модового поля, часто возникает нарушение юстировки сердцевин вследствие действия сил поверхностного натяжения. Это нарушение можно минимизировать следующими способами:
* сокращение времени плавления за счет неполного сваривания оптических волокон или же сокращение длины свободного конца оптического волокна в сварочном устройстве, чтобы концы оптических волокон в процессе сварки могли перемещаться на очень малое расстояние;
* использование компенсационных программ, таких как управление смещением сердцевины с помощью метода умышленного смещения осей.
Такой режим получил название RTC (Real Time Control). В этом режиме после юстировки сердцевин свариваемых оптических волокон и проведения процедуры предварительного оплавления происходит компенсация поперечного смещения сердцевин в сторону, противоположную производной расхождения.
Сварка оптических волокон осуществляется посредством чередования коротких импульсов тока высокой интенсивности с импульсами тока низкой интенсивности (релаксационными импульсами). При этом после сваривания в электрическом поле импульса высокой интенсивности в поле релаксационного импульса происходит перемещение оптических волокон под действием поверхностного натяжения. Количество чередующихся импульсов зависит от смещения сердцевин оптических волокон, которое постоянно контролируется сварочным аппаратом; как правило, количество импульсов не превышает 2-3.
Весьма существенное влияние на общую величину потерь, если свариваются оптические волокна с разными показателями преломления (N) сердцевины, может оказать составляющая Dрпп. Эта составляющая учитывает потери мощности оптического сигнала в результате несоблюдения условия полного внутреннего отражения на месте стыка двух оптических волокон, у которых показатели преломления сердцевин имеют различия. В этом случае часть оптического сигнала проникает через оболочку волокна и рассеивается. Ситуация усугубляется многократным отражением луча от границы "сердцевина/оболочка", каждое из которых (отражений) служит источником потери мощности. На практике нередки случаи, когда даже многократные повторные сварки не позволяют добиться малой величины потерь.
Наибольший вклад в суммарную величину потерь вносят потери от погрешности угловой юстировки осей оптических волокон и потери из-за разницы показателей преломления.
Международная электротехническая комиссия предлагает в качестве типичной характеристики сварного соединения оптических волокон, полученного в полевых условиях, величину вносимых потерь, равную 0,2 дБ (IEC 1073-1). При современном развитии технологии сварки оптических волокон этот показатель вполне достижим даже тем персоналом, который не обладает значительным опытом в этой области.
Соединение оптических волокон методом склеивания
Практически одновременно с методом сварки был разработан метод склеивания оптических волокон. Для получения клеевых соединений используют совмещение и фиксацию оптических волокон: в капилляре, в трубке с прямоугольным сечением, с помощью V-образной канавки и с помощью трех стержней в качестве направляющих. Оптические волокна соединяются поодиночке.
Технология получения таких соединений состоит из следующих этапов:
* подготовка оптических волокон к соединению (очистка, снятие буферных покрытий, скалывание);
* ввод оптического волокна в капилляр;
* наполнение иммерсионной жидкостью, гелем или клеем;
* регулирование соединения, юстировка оптических волокон;
* нанесение адгезивного вещества;
* цементирование адгезивного вещества с помощью ультрафиолетового излучения.
Клей, используемый для оптических волокон, должен иметь коэффициент преломления, близкий к коэффициенту преломления волокон. Он должен обеспечивать фиксированное положение соединенных оптических волокон, защищать место сращивания от воздействий окружающей среды, гарантировать прочность сростка при воздействии нагрузок в осевом направлении. К достоинствам этого метода следует отнести оперативность и отсутствие деформации сердцевин соединяемых оптических волокон. Это способствует тому, что в области стыка - малые потери, обеспечиваются хорошие механические свойства и т.п. Однако ограниченный срок службы и нестабильность во времени, а также весьма высокая чувствительность к повышению температуры и воздействию влажности являются факторами, сдерживающими распространение этого метода получения неразъемных соединений. В настоящее время он уступил свои позиции методу соединения оптических волокон с помощью механических соединителей.
Механические соединители оптических волокон
Механические соединители оптических волокон разрабатывались как более дешевый и быстрый способ сращивания оптических волокон. Применение аппарата для сварки оптических волокон сопряжено с необходимостью соблюдения ряда условий: для работы используется помещение, параметры которого (температурный диапазон, влажность, давление, вибрации и проч.) соответствуют требованиям производителей сварочного оборудования; также необходима организация питания от сети переменного тока с достаточно жестко регламентированными параметрами. При стоимости комплекта оборудования для сварки оптических волокон, составляющей десятки тысяч долларов США, амортизационные отчисления, а также техническое обслуживание и ремонт являются довольно дорогостоящими.
Достаточно высокие требования предъявляются также к персоналу, производящему работы по сварке оптических волокон. Часто этими же лицами производится наладка и обслуживание аппаратов для сварки оптических волокон (очистка направляющих поверхностей и зажимов, замена электродов и проч.), для чего требуются специалисты с высоким уровнем квалификации.
Всех этих сложностей можно избежать, применяя механические соединители оптических волокон. Конструкция оптических соединителей относительно проста. Основными узлами являются направляющие для двух оптических волокон и устройство фиксации волокон. Внутреннее пространство заполняется тиксотропным гелем для защиты открытых участков оптических волокон от воздействия влаги. Одновременно гель обладает иммерсионными свойствами - его показатель преломления близок к показателю преломления сердцевины волокна.
Процедура монтажа оптических соединителей является частью процедуры монтажа промежуточного или оконечного устройства - кабельной муфты, бокса или стойки. Размеры и форма оптических соединителей позволяют устанавливать их в кассету муфты или бокса аналогично сросткам оптических волокон, полученных путем сварки.
Процедура монтажа включает в себя следующие технологические операции:
* разделка кабелей;
* очистка оптических волокон от гидрофобного геля (при его наличии);
* снятие буферных покрытий соединяемых оптических волокон на участках длиной, рекомендуемой производителями оптических соединителей конкретного типа;
* скалывание оптических волокон;
* проверка качества скола волокон;
* введение соединяемых волокон в отверстия с направляющими;
* позиционирование волокон в соединителе для достижения оптимальных параметров соединения;
* фиксация оптических волокон в соединителе;
* тестовые измерения соединения.
Особое место среди оптических механических соединителей занимает RMS (Rotary Mechanical Splice) как наиболее сложный среди аналогов. Процесс его монтажа наиболее трудоемок, однако он позволяет достичь наименьших потерь при соединении одномодовых волокон. В отличие от остальных соединителей, где величина потерь главным образом зависит от качества скола торцевых поверхностей оптических волокон, этот соединитель позволяет юстировать волокна простым вращением вокруг своей оси стеклянных втулок, удерживающих подготовленные оптические волокна, и добиваться наилучших результатов.
Следует отметить, что применение механических соединителей является наиболее быстрым способом соединения оптических волокон. При этом вносимое затухание практически не отличается от затухания, создаваемого сварным соединением. Достаточно устойчивое функционирование механических соединителей в процессе эксплуатации позволяет уже сегодня рекомендовать их для широкого внедрения на телекоммуникационных сетях с невысокими требованиями к качеству соединений, а также в случаях, когда использование аппарата для сварки оптических волокон технологически затруднено или вообще невозможно. В дальнейшем статистика технической эксплуатации, а также совершенствование материалов компонентов механических соединителей, вероятно, определит их более широкое применение для строительства телекоммуникационных волоконно-оптических линий различных уровней.
Обращает на себя внимание тот факт, что механические соединители оптических волокон условно допускают однократное использование, однако на практике встречаются ситуации их многократного применения. Производители гарантируют качество соединения оптических волокон при повторном монтаже соединителя не более 2-3 раз, однако при повторном наполнении внутреннего пространства иммерсионным гелем (в тех конструкциях, где это предусмотрено) такие соединители использовались многократно без ущерба для качества стыков. Некоторыми производителями механических соединителей разработаны механизмы фиксации, предусматривающие использование специального ключа для открытия фиксатора.
Сегодня использование механических соединителей наиболее удобно при проведении аварийного ремонта волоконно-оптическихлиний для технологической операции организации временной вставки.