Точка и инвертированные символьные классы



При работе с программами, допускающими поиск в многострочном тексте, следует помнить, что точка обычно не совпадает с символом но­вой строки, но инвертированные классы типа r[~"]j обычно с этим сим­волом совпадают. Таким образом, переход от ". * к " [ ^" ] *"  может пре­поднести сюрприз.

 

3. Сокращенные обозначения классов: \w, \d, \s, \W, \D, \S

В большинстве программ существуют следующие удобные сокраще­ния для конструкций, которые обычно оформляются в виде класса:

\d Цифра.Обычно эквивалентно [0-9] или в некоторых программах с поддержкой Юникода - любым цифрам Юникода.

\D He-цифра.Обычно эквивалентно [ ^\d ].

\w Символ, входящий в слово.Часто эквивалентно [a-zA-Z0-9_], хо­тя одни программы исключают символ подчеркивания, а другие дополняют его всеми алфавитно-цифровыми символами в соот­ветствии с локальным контекстом. При поддержке Юни­кода \w обычно соответствует любому алфавитно-цифровому сим­волу (важное исключение: в пакете регулярных выражений Ja­va, util. regex и в PCRE, расширении для РНР, метасимвол \w ин­терпретируется в точности как [a-zA-Z0-9_]).

\W Символ, не входящий в слово.Обычно эквивалентно [ ^\w].

\s Пропуск.В системах, ограничивающихся поддержкой ASCII, часто эквивалентно [·\f\n\r\t\v]. В системах с поддержкой Юникода также часто включает управляющий символ «следую­щей строки» U+0085, а иногда и свойство \p{Z}.

\S He-пропуск(обычно эквивалентно [^\s]). Локальный контекст POSIX может влиять на интерпретацию некоторых обозначений (особенно \w). В программах с поддержкой Юникода у метасимвола \w обычно имеется больше потен­циальных совпадений - например, \р( L}) с символом подчеркивания.

4.Блоки, категории и свойства Юникода: \p{свойство}, \P{свойство}

На концептуальном уровне Юникод представляет собой отображение множества символов на множество кодов (<sp 141), но стандарт Юникода не сводится к простому перечислению пар. Он также определяет атрибу­ты символов (например, «этот символ является строчной буквой», «этот символ пишется справа налево», «этот символ является диакритичес­ким знаком, который должен объединяться с другим символом» и т. д.).

Уровень поддержки этих атрибутов зависит от конкретной програм­мы, но многие программы с поддержкой Юникода позволяют нахо­дить хотя бы некоторые из них при помощи конструкций г\р{атри­бут}} (символ, обладающий указанным атрибутом) и Г\Р{атрибут}} (символ, не обладающий атрибутом). Для примера рассмотрим конст­рукцию r\p{L}j('L' - атрибут «буква» в отличие от цифр, знаков препи­нания и тому подобного), которая представляет пример общего свойст­ва (также называемого категорией). Вскоре вы познакомитесь с дру­гими атрибутами, для проверки которых используются конструкции г\р{ }j и Г\Р{-}j, но общие свойства встречаются чаще всего.

Общие свойства перечислены в табл. 3.8. Каждый символ (а точнее, каждый кодовый пункт, включая и те, для которых символы не опре­делены) может быть идентифицирован по крайней мере по одному об­щему свойству. Имена общих свойств задаются одиночными символа­ми (V - буква, 'S' - специальный знак и т. д.), но в некоторых системах существуют более информативные синонимы ('Letter', 'Symbol' и т. д.). В частности, они поддерживаются в Perl.

Класс Синоним и описание
\p{L} \р{ Letter} - символы, считающиеся буквами
\p{М} \р{Магк} - различные символы, существующие не самостоятельно, а лишь в сочетании с другими базовыми символами (диакритические знаки, рамки и т. д.)
\p{Z}   \р{Separator} - символы, выполняющие функции разделителей, но не имеющие собственного визуального представления (разнообраз­ные пробелы и т. д.)
\p{S} \р{Symbol} - различные декоративные элементы и знаки
\p{N} \p{Number} -цифры
\p{P} \p{Punctuation} - знаки препинания
\p{C} \р{Other} - прочие символы (редко используется при работе с обыч­ным текстом)

В некоторых системах на однобуквенные имена свойств можно ссылать­ся без использования фигурных скобок (например, \pL вместо \p{L}). В отдельных системах требуется (или просто допускается) использовать префикс 'In' или 'Is* перед буквой (например, \p{IsL}). При опи­сании конкретных атрибутов будут приведены примеры ситуаций, когда префикс In/Is является обязательным.

Как показано в табл. ниже каждое однобуквенное общее свойство Юни-кода может делиться на несколько подсвойств, обозначаемых двумя буквами, например свойство «буква» может подразделять­ся на: «строчная буква», «прописная буква», «первая буква слова», «буква-модификатор» и «остальные буквы». Каждому из подсвойств соответствует точно один кодовый пункт.

Свойство Описание и синоним
\p{Ll} \p {Lowercase.Letter} - строчные буквы.
\p{Lu} \p{Uppercase_Letter} - прописные буквы.
\p{Lt} \p{Titlecase_Letter} - буквы, находящиеся в начале слова (напри­мер, символ Dz в отличие от строчного символа dz и прописного символа DZ).
\P(L&} Сокращенная запись для всех символов, обладающих свойствами \p{Ll},\p(Lu}H\p{Lt
\p{Lm} \p{Modifier_Letter} - небольшое подмножество специальных симво­лов, по внешнему виду схожих с буквами.
\p{Lo} \p{Other_Letter} - буквы, не имеющие регистра и не являющиеся модификаторами, в том числе буквы иврита, бенгали, японского и тибетского языков и т. д.
\p{Mn} \p{Non_Spacing_Mark} - «символы», изменяющие другие символы (акценты, умляуты, признаки тональности и т. д.).
\p{Mc} \p{Spacing_Combining_Mark} - модификаторы, занимающие собствен­ное место в тексте (в основном обозначения гласных в тех языках, в которых они поддерживаются, включая бенгальский, гуджарати, тамильский, телугу, каннада, малаялам, синхала, мьянмар и кхмерский).
\p{Me} \p{Enclosing_Mark} - небольшой набор знаков, внутри которых могут находиться другие символы (круги, квадраты, ромбы и «буквицы»).
\p{Zs} \p{Space_Separator} - различные типы пробелов (обычный пробел, неразрывный пробел и пробелы фиксированной ширины).
\p{Zl} \p{Line_Separator} - символ LINE SEPARATOR (U+2028).
\p{Zp} \p{Paragraph_Separator} - символ PARAGRAPH SEPARATOR (U+2029).
\p{Sm} \p{Math_Symbol} -+,-,/,<, ...
\p{Sc} \p{Currency_Symbol} - $, C, ¥, €, ...
\p{Sk} \p{Modlfier_Symbol} - в основном разновидности комбинационных символов, но также включает ряд самостоятельных символов.
\p{So} \p{Other_Symbol} - различные декоративные символы, псевдографи­ка, азбука Брайля и т. д.
\p{Nd} \p{Decimal_Digit_Number} - цифры от 0 до 9 в различных алфавитах (кроме китайского, японского и корейского).
\P(N1} \p{Letter_Number} - в основном римские цифры.
\p{No} \p{Other_Number} - числа в верхних и нижних индексах, дроби; сим­волы, представляющие числа, которые не являются цифрами (кро­ме китайского, японского и корейского алфавитов).
\p{Pd} \p{Dash_Punctuation} - всевозможные дефисы и отрезки.
\p{Ps} \p{Open_Punctuatlon} - такие символы, как (, ^, «, ...
\p{Pe} \p{Close_Punctuation} - такие символы, как ), **% »,
\p{Pi} \p{Initial_Punctuation} - такие символы, как «, ", <, ...
\p{Pf} \p{Final_Punctuation} - такие символы, как », ', >, ...
\p{Pc} \p{Connector_Punctuatlon} - знаки препинания, имеющие особый лингвистический смысл (например, символ подчеркивания).
\p{Po} \p{Other_Punctuation} - остальные знаки препинания:!, &, •,:,;, ...
\p{Cc} \p{Control} - управляющие символы ASCII и Latin-1 (TAB, LF, CR...)
\p{Cf} \p{Format} - неотображаемые символы, являющиеся признаками форматирования.
\p{Co} \p{Private_Use} - кодовые пункты, предназначенные для закрытого использования (логотипы компаний и т. д.).
\p{Cn} \p{Unassigned} - кодовые пункты, которым не присвоены символы.

5.Операции с классами: [[a-z]&&[^aeiou]]

Пакет регулярных выражений для Javaот Sunподдерживает операции множеств с символьными классами (объединение, вычитание, пересече­ние). Синтаксис их несколько отличается от синтаксиса простого вычи­тания, описанного в предыдущем разделе (в частности, в языке Javaсинтаксис операции вычитания выглядит несколько странно, например множество всех согласных букв латинского алфавита определяется фор­мулой [[a-z]&&[~aeiou]]). Прежде чем рассматривать операцию вычита­ния в подробностях, познакомимся с двумя основными операциями над символьными классами - объединения (OR) и пересечения (AND).

Операция объединения включает в классы новые символы. Запись выглядит как определение класса внутри класса: выражение [abcxyz] также можно записать в виде [[abc][xyz]], [abc[xyz]] или [[abc]xyz]. Операция объединения создает новое множество из всех элементов, присутствующих хотя бы в одном из множеств-аргументов. На концеп­туальном уровне она аналогична оператору «поразрядной дизъюнк­ции», который во многих языках представляется оператором | или or В символьных классах объединения в основном используются для удобства записи, хотя в некоторых ситуациях полезной оказывается возможность включения инвертированных классов.

Операция пересечения является концептуальным аналогом оператора «поразрядной конъюнкции». Итоговое множество состоит из элемен­тов, присутствующих в обоих множествах-аргументах. Например, вы­ражение [\p{InThai}&&\P{Cn}] совпадает с кодовыми пунктами блока Thai, с которыми ассоциируются символы. Для этого вычисляется пе­ресечение (т. е. совокупность символов, входящих в каждое из мно­жеств) между классами \р{InThai} и \Р{Сn}. Как говорилось выше, \Р{-} (с прописной Р) совпадает со всем, что не обладает заданным ат­рибутом. Таким образом, \Р{Сn} совпадает со всеми кодовыми пункта­ми, которые не обладают атрибутом отсутствия ассоциированных символов, а проще говоря, со всеми пунктами, у которых имеются ас­социированные символы (если бы разработчики Sun поддержали атри­бут Assigned вместо \Р{Сn} в данном примере, можно было бы использо­вать запись \p{Assigned}).

Будьте внимательны и не путайте пересечение с объединением. Инту­итивность этих терминов зависит от точки зрения. Например, конст­рукция [[this][that]] обычно формулируется в виде «допускаются символы, совпадающие с [this] или [that]», но ее с таким же успехом можно прочитать как «список допустимых символов состоит из [this] и [that]». Две точки зрения на одно и то же явление.

Смысл операции пересечения более очевиден, например, выражение [\р{InThai}&&\P{Cn}] обычно читается как: «символы, соответствую­щие одновременно классу \р{InThai} и \Р{Сn}, хотя его можно прочи­тать и как: «список символов, представляющий собой пересечение

\p{InThai} и \Р{Сn}».

Эти две различных точки зрения могут вносить путаницу: вместо ис­пользования союзов И и ИЛИ иногда бывает удобнее использовать тер­мин ПЕРЕСЕЧЕНИЕ и союз И.

Вычитание

Возвращаясь к примеру [\p{InThai }&&\P{Cn} ], будет полезно заметить, что конструкция \Р{Сn} эквивалентна [~\р(Сn}], поэтому все выраже­ние можно переписать в несколько усложненном виде [\р{InThai}&&[|\р{Сn}]]. Более того, категория «пункты с ассоциированными сим­волами в блоке Thai» эквивалентна категории «все пункты блока Thai за исключением пунктов, не имеющих ассоциированных символов». Двойное отрицание слегка усложняет формулировку, но вы можете легко убедиться, что выражение [\p(InThai}&&[^\p(Cn}]] означает «\p{InThai} минус \р{Сn}».

Итак, мы возвращаемся к примеру [[a-z]&&[~aeiou]], в нем продемонстрирована операция вычитания классов. Суть состоит в том, что выражение [this&&[~thaf]]означает: «[this] минус [that]».Лично у меня от двойного отрицания && и [^…] голова идет кругом, поэтому я предпочитаю просто запомнить шаблон […&&[^…]]

6.Комбинационные последовательности Юникода: \X

Perl и РНР поддерживают метасимвол \Х как сокращение шаблона \P{M}\p{M}*, который представляет собой расширенный вариант . . Он соответствует базовому символу (любому, не соответствующему \р{М}), за которым может следовать произвольное число комбинационных символов (все, что соответствует \р{М}).

Юникод определяет начертание от­дельных символов с диакритическими знаками, например à (базовый символ a U+0061 комбинируется с диакритическим знаком ‘ U+0300) как комбинацию из базового и комбинационного символов.

При попытке отыскать совпадения со словами «francais» и «français» использование шаблона f ran. ais или f ran[c?]ais может не обеспечи­вать результат, поскольку в обоих шаблонах предполагается, что символу ç соответствует один кодовый пункт Юникода U+00C7, и не учи­тывается, что этому символу может соответствовать символ 'с' со сле­дующей за ним седилью (U+0063 U+0327). Для обеспечения точного со­впадения можно было бы использовать шаблон f ran[c ¸I ç ]ais, но в данном случае неплохой заменой для fran.ais мог бы служить шаб­лон fran\Xais.

Кроме того, что \Х соответствует любым комбинационным символам, существует еще два отличия \Х от точки. Первое отличие заключается в том, что \Х всегда соответствует символу новой строки и другим за­вершителям строк Юникода,тогда как поведение точки зави­сит от выбранного режима обработки регулярных выражений. Второе отличие состоит в том, что в однострочном режиме точка соот­ветствует любому символу, тогда как \X не может соответствовать на­чальному комбинационному символу (не идущему вслед за базовым).

7. Символьные классы POSIX: [[:alpha:]]

То, что мы обычно называли символьным классом, в стандарте POSIXбыло решено назвать групповым выражением (bracket expression). В POSIXтермин «символьный класс» относится к специальной конст­рукции, используемой внутри группового выражения, которую мож­но рассматривать как своего рода предшественника свойств символов в Юникоде.

Символьный класс POSIX представляет собой одну из нескольких спе­циальных метапоследовательностей, используемых внутри группо­вых выражений в стандарте POSIX. Примером является конструкция [:lower:], соответствующая любой букве нижнего регистра в текущем локальном контексте. Для обычного английского текста кон­струкция [: lower:] означает интервал a-z. Поскольку вся метапоследовательность действительна только внутри группового выражения, класс, сравнимый с [a-z], имеет вид [[ :lower: ]]. Да, это выглядит уродливо, но предоставляет дополнительную возможность включения других символов – ö, ň и т. д. (если в локальном контексте они дейст­вительно являются символами «нижнего регистра»).

Точный список символьных классов POSIX зависит от локального контекста, но следующие конструкции поддерживаются в большинст­ве систем:

 

:alnun: алфавитные символы и цифровые символы
:alpha: алфавитные символы
:blank: пробел и табуляция
:cntrl: управляющие символы
:digit: цифры
:graph: отображаемые символы (не пробелы, не управляющие символы и т. д.)
:lower: алфавитные символы нижнего регистра
:print: аналог [:graph: ], но включает пробел
:space: все пропуски ([:blank: ], символ новой строки, возврат курсора и т. д.)
: upper: алфавитные символы верхнего регистра
: xdlgit: цифры, допустимые в шестнадцатеричных числах (т. е. 0-9a-fA-F)
:punct: Знаки препинания

Системы, в которых поддерживаются свойства Юникода (^ 159), мо­гут по своему усмотрению расширять поддержку этих свойств до кон­струкций POSIX. Обычно предпочтение отдается свойствам Юникода, поскольку они обладают большими возможностями, нежели их анало­ги в POSIX.

 

8. Объединяющие последовательности POSIX: [[.span-11.]]

В локальном контексте могут определяться объединяющие последова­тельности, описывающие интерпретацию некоторых символов или совокупностей символов при сортировке и других операциях. Напри­мер, в испанском языке символы ll (как, например, в слове tortilla), традиционно сортируются, как если бы это был одиночный символ между l и m, а символ Я в немецком языке находится между s и t, но сортируется как два символа ss. Эти правила выражаются объединяю­щими последовательностями, которым, например, могут быть присво­ены имена span-ll и eszet.

В механизме регулярных выражений, соответствующем стандарту POSIX, объединяющие последовательности, отображающие несколь­ко физических символов на один логический символ (как в span-11), рассматриваются как один символ. Это означает, что символьный класс типа [~abc] совпадет с последовательностью ll.

Для включения элементов объединяющих последовательностей в груп­повые выражения используется обозначение [. .]: выражение torti[[.span-11.]]a совпадает с tortilla. Объединяющая последователь­ность позволяет осуществлять сравнение символов, которые представ­ляют собой комбинации других символов. Кроме того, становятся воз­можными ситуации, при которых групповое выражение совпадает с последовательностью из нескольких физических символов!

 

9. Символьные эквиваленты POSIX: [[=n=]]

В некоторых локальных контекстах определяются символьные экви­валенты {character equivalents), указывающие, что какие-то из симво­лов должны считаться идентичными при выполнении сортировки и других аналогичных операций. Например, локальный контекст мо­жет определить класс-эквивалент n, содержащий символы n и ň или класс a содержащий символы a, à и á. Используя запись, аналогичную приведенной выше конструкции [: … :], и заменив двоето­чия знаками равенства, можно ссылаться на классы-эквиваленты в групповых выражениях; например, [[=n=][=a=]] совпадает с любым из перечисленных символов.

Если символьный эквивалент с однобуквенным именем используется, но не определяется в локальном контексте, он по умолчанию совпада­ет с объединяющей последовательностью с тем же именем. Локальные контексты обычно содержат объединяющие последовательности для всех обычных символов ([. а. ], [. Ь. ], [ .с. ] и т. д.), поэтому при отсут­ствии специальных эквивалентов конструкция [[=n=][=a=]] по умол­чанию считается идентичной [na].

 

  1. Якорные метасимволы и другие проверки с нулевой длиной совпадения.

1. Начало строки, начало логической строки: ^, \A

Метасимвол ^ совпадает в начале текста, в котором производится по­иск, или в расширенном режиме привязки к границам строк  -в позиции после любого символа новой строки. В некоторых системах в расширенном режиме ^  также может совпадать с завершителями строк Юникода.

Метасимвол \A (если он поддерживается) совпадает только в начале текста независимо от режима поиска.

2. Конец строки, конец логической строки: $, \Z, \z

Концепция «конца строки» несколько слож­нее парной ей концепции начала строки. В разных реализациях $ ин­терпретируется по-разному. В самом распространенном варианте он совпадает с концом целевого текста перед завершающим символом но­вой строки. Это сделано для того, чтобы выражения вида s$ («строка, заканчивающаяся символом s») совпадали с комбинациями символов '•••s\n' в тексте, когда строки завершаются буквой s и символом новой строки.

В других распространенных интерпретациях $ совпадает только в кон­це всего фрагмента или перед любым символом новой строки. В неко­торых системах с поддержкой Юникода символы новой строки в этих правилах заменяются завершителями строк Юникода. (На­пример, язык Java реализует самую сложную семантику $ в отноше­нии завершителей Юникода)

Выбор режима может повлиять на интерпретацию $, в резуль­тате он будет соответствовать любым промежуточным символам новой строки в блоке текста (а также любым завершителям Юникода).

Метасимвол \Z (если он поддерживается) обычно соответствует мета­символуr$ в стандартном режиме, что часто означает совпадение в конце текста или перед символом новой строки, завершающим текст. Парный метасимвол \z совпадает только в конце строки без учета возможных символов новой строки.

3. Начало совпадения (или конец предыдущего совпадения): \G

Метасимвол \G впервые появился в Perl и предназначался для проведе­ния глобального поиска с модификатором /g . Он совпадает с по­зицией, в которой завершилось предыдущее совпадение. При первой итерации \G совпадает только в начале строки, как и метасимвол \A.

Если попытка поиска завершилась неудачей, позиция \G возвращается в начало строки. Таким образом, при многократном применении регу­лярного выражения (как при использовании команды s/-/-/g или дру­гих средств глобального поиска) неудача при очередном поиске приво­дит к сбросу позиции \G для применения следующего выражения.

В Perl метасимвол \G обладает тремя уникальными особенностями, которые мне кажутся весьма интересными и полезными.

· Позиция, связанная с \G, является атрибутом целевой строки, а не регулярного выражения. Это позволяет последовательно приме­нить к строке несколько регулярных выражений, причем метасим­вол \G в каждом из них продолжит поиск с той позиции, на кото­рой он был прерван для предыдущего выражения.

· Операторы регулярных выражений Perl поддерживают модифика­тор /с, при помощи которого можно указать, что в случае неудачного поиска позиция \G не сбрасывается, а остается в по­следней позиции. В сочетании с первым пунктом это помогает орга­низовать проверку по нескольким регулярным выражениям с од­ной позиции целевого текста, которая смещается только при обна­ружении совпадения.

· Текущую позицию метасимвола \G можно получить и изменить с использованием средств, не имеющих отношения к регулярным выражениям (функция pos). Например, ее можно задать так, чтобы поиск начинался с заданной позиции. Кроме того, поддерж­ка этой возможности в языке позволяет имитировать функциональ­ность предыдущего пункта, если она не поддерживается напрямую.

Примеры практического использования этих возможностей приводят­ся во врезке на следующей странице. Несмотря на наличие этих удоб­ных возможностей, у метасимвола \G в Perl имеется недостаток - он работает надежно лишь в том случае, если находится в самом начале регулярного выражения. К счастью, именно там он используется наи­более естественным образом.


Дата добавления: 2018-04-04; просмотров: 457; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!