CascadiaPHP 2024

Символьные классы

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

Символьный класс соответствует одиночному символу входной строки; символ должен входить в набор символов, который определили в классе, если только первый символ в классе не циркумфлекс «^», тогда символ входной строки не должен входить в класс. Если циркумфлекс «^» нужен как член класса, проверяют, чтобы он не шёл первым символом в описании класса, либо экранируют циркумфлекс обратным слешем.

Символьный класс [aeiou], например, соответствует любой гласной букве в нижнем регистре, тогда как класс [^aeiou] соответствует любому согласному символу нижнего регистра. Обратите внимание, что циркумфлекс — просто удобный способ определить символьный класс за счёт перечисления тех символов, которые не должны входить в класс. Символ начала строки — не утверждение: он по-прежнему использует символ из входной строки и завершается ошибкой, если текущий указатель находится в конце строки.

При регистронезависимом сопоставлении буквы символьного класса соответствует версии символа как в верхнем, так и в нижнем регистре. Поэтому символьный класс [aeiou] соответствует как букве «A», так и букве «a». Аналогично, класс [^aeiou] не соответствует ни «A», ни «a», тогда как в регистрозависимом режиме совпадение бы состоялось.

Внутри символьного класса у символа перевода строки «\n» нет специального значения, независимо от наличия модификаторов PCRE_DOTALL и PCRE_MULTILINE. Символьные классы, построенные на отрицании, например [^a], всегда соответствуют символу перевода строки.

Символ минус «-» (дефис) внутри класса используется для задания символьного диапазона. Например, [d-m] соответствует любому символу, находящемуся между «d» и «m», включая сами символы «d» и «m». Если «-» необходим, как член класса, он должен находиться в такой позиции, в которой он не может интерпретироваться как диапазон (как правило, это первый и последний символ описания класса), либо экранироваться при помощи обратного слеша.

Недопустимо записывать закрывающую квадратную скобку «]» как границу символьного диапазона. Например, парсер интерпретирует шаблон «[W-]46]» как символьный класс, который состоит из двух символов: «W» и «-», за которыми идёт строка «46]», поэтому шаблон будет соответствовать строкам «W46]» или «-46]». Чтобы всё же задать символ «]» в описании диапазона, его нужно заэкранировать обратным слешем, например, парсер интерпретирует шаблон [W-\]46] как символьный класс, который состоит из символьного диапазона вместе с двумя последующими символами «4» и «6». Такого же результата можно достичь через шестнадцатеричное или восьмеричное представление символа «]».

Диапазоны символьных классов определяют последовательностью ASCII-символов, которые указывают через символ «-». Диапазоны также разрешено определять числами, например [\000-\037]. Диапазон будет соответствовать буквам в нижнем и верхнем регистрах, если в диапазон включили буквы и установили регистронезависимое сопоставление. Например, диапазоны [W-c] и [][\^_`wxyzabc] эквивалентны, парсер сопоставляет символы без учёта регистра, а если установлена таблица символов для французской локали «fr», парсер будет сопоставлять символы из диапазона [\xc8-\xcb] ударному «E» в обоих регистрах.

Типам символов \d, \D, \s, \S, \w и \W также разрешено присутствовать в символьных классах и добавлять символы, которые им соответствуют, в класс. Например, класс [\dABCDEF] соответствует любой шестнадцатеричной цифре. Символ «^» указывают с типами символов в верхнем регистре, чтобы указать более узкий набор символов. Например, класс [^\W_] соответствует любой букве или цифре, но не символу подчёркивания.

Все небуквенно-цифровые символы, кроме \, -, ^ в начале и символа «]» в конце, не относятся к специальным символам в символьном классе, но экранирующий слеш перед ними не навредит. Символ конца шаблона — всегда специальный символ и должен быть заэкранирован внутри выражения.

Язык Perl поддерживает нотацию POSIX для символьных классов. Это включает имена в квадратных скобках: [: и :]. Модуль PCRE также поддерживает эту тип записи. Например, шаблон [01[:alpha:]%] совпадёт с «0», «1», любым алфавитным символом или символом «%». Модуль PCRE поддерживает следующие имена классов:

Символьные классы
alnumбуквы и цифры
alphaбуквы
asciiсимволы с кодами 0–127
blankтолько пробел или символ табуляции
cntrlуправляющие символы
digitдесятичные цифры (то же самое, что и \d)
graphпечатные символы, исключая пробел
lowerстрочные буквы
printпечатные символы, включая пробел
punctпечатные символы, исключая буквы и цифры
spaceпробельные символы(почти то же самое, что и \s)
upperпрописные буквы
wordсимволы «слова» (то же самое, что и \w)
xdigitшестнадцатеричные цифры
Класс пробельных символов (space) — это горизонтальная табуляция (HT, 9), перевод строки (LF, 10), вертикальная табуляция (VT, 11), разрыв страницы (FF, 12), возврат каретки (CR, 13) и пробел (32). Учтите, что этот список включает вертикальную табуляцию (VT, код 11). Это отличает «space» от \s, который не включает этот символ (для совместимости с Perl).

Название word — это модуль Perl, а blank — модуль GNU, начиная с версии Perl 5.8. Другой модуль Perl — отрицание, которое указывается символом ^ после двоеточия. Например, [12[:^digit:]] совпадёт с «1», «2», или с любой не-цифрой.

В режиме UTF-8 символы со значениями, которые превышают 128, не совпадут ни с одним из символьных классов POSIX. Начиная с libpcre 8.10 некоторые символьные классы изменили, чтобы использовать свойства символов Unicode, в этом случае упомянутое ограничение не применяется. Подробнее об этом рассказывает » руководство PCRE(3).

Свойства символов Unicode могут возникнуть внутри символьного класса. Они не могут быть частью диапазона. Символ минус (дефис), после символьного класс Unicode будет совпадать буквально. Попытка закончить диапазон свойством символа Unicode вызовет предупреждение.

add a note

User Contributed Notes 4 notes

up
20
greaties at ghvernuft dot nl
2 years ago
From deep down the PCRE manual at http://www.pcre.org/pcre.txt :

\d any decimal digit
\D any character that is not a decimal digit
\h any horizontal white space character
\H any character that is not a horizontal white space character
\s any white space character
\S any character that is not a white space character
\v any vertical white space character
\V any character that is not a vertical white space character
\w any "word" character
\W any "non-word" character
up
4
Julian
1 year ago
Examples with Character classes

<?php

$stringA
= "1 In the beginning God created the heavens and the earth.";
$stringB = preg_replace('/[[:^alnum:]]/', '', $stringA); // string(46) "1InthebeginningGodcreatedtheheavensandtheearth"
$stringC = preg_replace('/[[:^alpha:]]/', '', $stringA); // string(45) "InthebeginningGodcreatedtheheavensandtheearth"
$stringD = preg_replace('/[[:^ascii:]]/', '', "Pokémon"); // string(6) "Pokmon"
$stringE = preg_replace('/[[:^blank:]]/', '*', $stringA); // string(57) "* ** *** ********* *** ******* *** ******* *** *** ******"
$stringF = preg_replace('/[[:blank:]]/', '-', $stringA); // string(57) "1-In-the-beginning-God-created-the-heavens-and-the-earth."

$stringG = sprintf("Vertical Tabulation: %s", chr(11)); // string(22) "Vertical Tabulation: "
$stringH = preg_replace('/[[:cntrl:]]/', '', $stringG); // string(21) "Vertical Tabulation: "
$stringLengthG = strlen($stringG); // int(22)
$stringLengthH = strlen($stringH); // int(21)

$stringI = preg_replace('/[[:digit:]]/', '', 'My age is 35'); //string(10) "My age is "
$stringJ = preg_replace('/[[:^digit:]]/', '', 'My age is 35'); // string(2) "35"

$stringK = preg_replace('/[[:^graph:]]/', '', $stringG); // string(19) "VerticalTabulation:"
$stringL = preg_replace('/[[:graph:]]/', '', $stringG); // string(3) " "

$stringM = preg_replace('/[[:lower:]]/', '', $stringG); // string(6) "V T: "
$stringN = preg_replace('/[[:^lower:]]/', '', $stringG); // string(16) "erticalabulation"

$stringO = preg_replace('/[[:^print:]]/', '', $stringG); // string(21) "Vertical Tabulation: "
$stringP = preg_replace('/[[:print:]]/', '', $stringG); // string(1) " "

$stringQ = preg_replace('/[[:punct:]]/', '', $stringG); // string(21) "Vertical Tabulation "
$stringR = preg_replace('/[[:^punct:]]/', '', $stringG); // string(1) ":"

$stringS = preg_replace('/[[:space:]]/', '', $stringG); // string(19) "VerticalTabulation:"
$stringT = preg_replace('/[[:^space:]]/', '', $stringG); // string(3) " "

$stringU = preg_replace('/[[:upper:]]/', '', $stringG); // string(20) "ertical abulation: "
$stringV = preg_replace('/[[:^upper:]]/', '', $stringG); // string(2) "VT"

$stringW = preg_replace('/[[:word:]]/', '', $stringG); // string(4) " : "
$stringX = preg_replace('/[[:^word:]]/', '', $stringG); // string(18) "VerticalTabulation"

$stringY = preg_replace('/[[:xdigit:]]/', '', 'abcdefghijklmnopqrstuvwxyz0123456789'); // string(20) "ghijklmnopqrstuvwxyz"
$stringZ = preg_replace('/[[:^xdigit:]]/', '', 'abcdefghijklmnopqrstuvwxyz0123456789'); // string(16) "abcdef0123456789"
up
6
wordragon at wrestingcontrol dot com
6 years ago
The documentation says:

"The character types \d, \D, \s, \S, \w, and \W may also appear in a character class, and add the characters that they match to the class."

It does not stress that other escape types may not. I wanted to split a string on either a comma (","), or a new line "\n". When my input stream began to include "\r\n", I decided to change "\n" to "\R". Unfortunately, my test string did not include a capital "R", or I might have found the problem sooner. My '/[\R,]/' was simply splitting on comma and the letter "R".

My test string...
"The Yum-Yum Company\r\n127 bernard street"

What DID work: '/(?:\R|,)+/'

["The Yum-Yum Company","127 bernard street"]

Given character classes only match one character, I can see clearly why my expectations were justifiably dashed, but hopefully this comment will save time for someone else.

I might add, this has taught me the value of PCRE_EXTRA (modifier "X"), which I have begun to use routinely now.
up
-9
php at delegated dot net
5 years ago
Some characters may not work as expected within a custom class. MS double quote for example is unrecognised when included in a class but is recognised otherwise.

ie:
<?php
preg_match_all
('/<a href=("|“)/')
?> will match but
<?php
preg_match_all
('/<a href=["“]/')
?> will not
when applied to <a href=“path">
To Top