Автор Тема: Регулярни изрази част 4  (Прочетена 4647 пъти)

0 Потребители и 1 Гост преглежда(т) тази тема.

Stan

  • Hero Member
  • *****
  • Благодарности
  • -Казани: 27
  • -Получени: 135
  • Публикации: 641
Регулярни изрази част 4
« -: 20 Януари 2012, 22:36:45 »
Здравейте отново в последния урок от поредицата за регулярни изрази.В този урок ще се запознаем общо казано с някои похвати за по-лесно и съкратено писане на регулярни изрази както и някои важни неща,за които не сме споменали в предишните уроци.

Започваме с предефинираните класове от символи:

\d - намира съвпадение с всяка десетична цифра - това е еквивалент на класа [0-9]
\D - намира съвпадение с всеки символ, който не е цифра - това е еквивалент на класа [^0-9]
\s - намира съвпадение с всеки празен символ - това е еквивалент на класа [ \t\n\r\f\v]
\S - намира съвпадение с всеки не празен символ - това е еквивалент на класа [^ \t\n\r\f\v]
\w - намира съвпадение с всеки буквеноцифров символ - това е еквивалент на класа [a-zA-Z0-9_]
\W - намира съвпадение с всеки не буквеноцифров символ - това е еквивалент на класа [^a-zA-Z0-9_]
\h - намира съвпадение с шеснадесетична цифра - това е еквивалент на класа [0-9a-fA-F]
\H - намира съвпадение със символ, който не е шеснадесетична цифра -  това е еквивалент на класа [^0-9a-fA-F]

и други.

Ето и един прост пример за намиране на едно или повече съвпадения с празно пространство в символен стринг:(доста популярен пример)

Код: PHP
  1. $pattern='/\s+/'; // това е идентично на /[ \t\n\r\f\v]+/

И още един за намиране на едно или повече съвпадения на цифри от 0 до 9 в символен низ:

Код: PHP
  1. $pattern='/\d+/'; // това е идентично на /[0-9]+/

Важно е да се отбележи,че предефинираните класове от своя страна могат да бъдат включвани в класове от символи:

Код: PHP
  1. $pattern='/[a-z\d]+/'; // това е идентично на /[a-z0-9]+/

POSIX-класове от символи:

[[:alpha:]] - символ от азбука
[[:alnum:]] - горното или цифра
[[:blank:]] - интервал или таб
[[:cntrl:]] - контролен символ
[[:digit:]] - цифра
[[:lower:]] - малка буква
[[:upper:]] - главна буква
[[:print:]] - printable-символ
[[:punct:]] - пунктуационен символ
[[:space:]] - whitespace-символ (вкл. и нов ред)
[[:xdigit:]] - шеснадеситична цифра

Може да видите останалите тук както и на кои класове отговарят.

Символни свойства(character properties):

С конструкцията \p{} може да намирате съвпадение на символи, имащи съответното свойство подобно на POSIX - \p{Alnum}, \p{Alpha}, \p{Blank}, \p{Cntrl}, \p{Digit}, \p{Graph}
Може да проверите дали даден символ е от кирилицата : \p{Cyrillic}, а за всички езици \p{L} (използвайте тези свойства за азбуките с флаг "u", който е един от режимите за които ще споменем след малко)

Ето пример за намиране на съвпадение с букви от кирилицата и латиницата обединени в клас:

Код: PHP
  1. $pattern='/[a-zA-Z\p{Cyrillic}]+/u';

Котви("пространствени дупки"):

\A - съвпада с началото на текстов низ
\z - съвпада с края на низ
\b - отговаря на граница на дума (когато е извън клас, вътре означава backspace)
\B - отговаря на място, което не е граница на дума

Тук попадат и метасимволите "^","$"

Ето няколко примера:

Код: PHP
  1. $pattern='/\bsize\b/';

Резултата със символен низ "size is a word": size is a word

Важно е да се каже,че ще се намери съвпадение дори и символния низ да започва с шаблона(както е в случая), за който се търси независимо че нямаме някакво пространство в началото.


Код: PHP
  1. $pattern='/\Bsize\B/';

Резултата със символен низ "heresizeisnotword": heresizeisnotword
Резултата със символен низ "size is a word, but in filesize not" и шаблон (\Bsize) : size is a word, but in filesize not

Режими при компилация(флагове):

i(ignorecase) - при съпоставянето на шаблона и символния низ се пренебрегва разликата между малки и големи букви.
x(verbose) - позволява многословните регулярни изрази, които могат да се съставят по-ясно и разбираемо.
s(dotall) - прави така, че метасимвола "." да пасва с всеки символ, дори със символа за нов ред.(вижте метасимвола "." в първи урок)
g(global) - намира всички съвпадения с даден шаблон в символен низ.
m(multiline) - многоредови съвпадения, оказва влияние върху "^" и "$".

и други..

Ето няколко примера(забележете къде се поставят):

Код: PHP
  1. $pattern='/filesize/i';

Резултат със символен низ "FiLeSiZe" : FiLeSiZe

Код: PHP
  1. $pattern='/word/g';

Резултат със символен низ "word, another word and again word" : word, another word and again word

Код: PHP
  1. $pattern='/.+/s';

Резултат със символен низ "word,(нов ред, натиснете enter) another word" : word,(нов ред) another word

Ами както се казва "Това беше всичко приятели" :).Надявам се да разберете нещата, не са трудни нужно е повечко упражнение и интерес от ваша страна.Въпреки, че това далеч не е всичко за регулярните изрази,тези знания дават добри основи и може да правите по-добри шаблони за каквото и да е било от може би над 50% от тези които са в мрежата.Очаквам да поствате вашите шаблони в тази тема.
« Последна редакция: 30 Януари 2012, 11:52:46 от abcd »

howto

  • Sr. Member
  • ****
  • Благодарности
  • -Казани: 44
  • -Получени: 5
  • Публикации: 341
Re: Регулярни изрази част 4
« Отговор #1 -: 11 Юни 2012, 15:45:27 »
Може ли да ми покажеш само как да премахна следния проблем .

Когато израза е поставен така :
Код: PHP
  1. $Template_Blank=preg_replace("/\{{font\}}(.+?)/s", '<font size="$1">',$Template_Blank);
и сложа {{font}}9 всичко е ок
Код: HTML
  1. <font size="9">
Но когато опитам да му задам втори число {{font}}-9 или +9 или сложа 22 дава следния резултат
Код: HTML
  1. {{font}}12
  2. <font size="1">2
  3. {{font}}-1
  4. <font size="-">1
Как да го поправя ?

Stan

  • Hero Member
  • *****
  • Благодарности
  • -Казани: 27
  • -Получени: 135
  • Публикации: 641
Re: Регулярни изрази част 4
« Отговор #2 -: 11 Юни 2012, 16:10:22 »
Райчо, проблема идва, че ограничаваш "алчноста" на метасимвола "+" (имам прведвид комбинацията - "+?"), и го караш да се мачне с единствен произволен символ след font във фигурни скоби.Също ти ще изпозлваш само числа затова метасимвола "." не е удачен в случая.Ето ти един примерен вариянт за числа както и плюсче или минусче отпред:

Код: PHP
  1. $Template_Blank=preg_replace('/\{\{font}}((-|\+)?\d+)/', '<font size="$1">',$Template_Blank);

howto

  • Sr. Member
  • ****
  • Благодарности
  • -Казани: 44
  • -Получени: 5
  • Публикации: 341
Re: Регулярни изрази част 4
« Отговор #3 -: 11 Юни 2012, 16:15:09 »
Супер е!Но сега ще трябва да говориш пак :D .  Винаги когато имам {{ }} трябва да освобождавам   /\{\{font}} ?По следния начин, който предложи ти ? Уж ги прочетох... До колкото разбирам \ черта освобождава http:// при което // в php е коментар ще го освободи и няма да бъде коментар . Но ти ще ми изясниш по-добре че нещо не схващам пак цялата тая работа с чертички и наклонени :D
« Последна редакция: 11 Юни 2012, 16:17:41 от howto »

Stan

  • Hero Member
  • *****
  • Благодарности
  • -Казани: 27
  • -Получени: 135
  • Публикации: 641
Re: Регулярни изрази част 4
« Отговор #4 -: 11 Юни 2012, 16:40:06 »
Тази черта backslash е метасимвол(специален символ), който екранира(ескейпва) други такива.Аз съм го обяснил във втората част мисля.Как пирмерно при php,когато пишеш стринг в двойни или единични кавички се налага да ги ескейпваш в самия стринг ако се срещат:

Код: PHP
  1. $text = 'O\'Really';
  2. $html = "<a href=\"link.com\"></a>";

Ето ти един пример с регулярен израз,за да ти стане по-ясно.Искаш например да намери в стринг следната безсмислица: [dqdo koleda] и пишеш следния шаблон:

Код: PHP
  1. $pattern = '[dqdo koleda]';

Е да ама не, няма да стане.Тъй като квадратните скоби са метасимволи и образуват клас този шаблон коренно му се видоизменя значението - образува се клас в който се казва да се търси за символ "d" или "q" или "o" или "k" или "l" или "e" или "a" или празен интервал.За да премахнем класа и да търсим дядо коледа в някакви си скоби е достатъчно да ескейпнем едната квадратна скоба:

Код: PHP
  1. $pattern = '\[dqdo koleda]';

Така е и с другите метасимволи.В случая с фигурните скоби даже не е необходимо да се ескейпват:

Код: PHP
  1. $Template_Blank=preg_replace('/{{font}}((-|\+)?\d+)/', '<font size="$1">',$Template_Blank);

Ако имаше числа между тях, тогава щеше да бъде задължително, защото щеше да значи диапазон на съвпадение с предходния символ или група или клас, но е добре като навик да си изградиш да си ги ескейпваш за да не се чудиш защо не стават понякога нещата.  ;)

Допълнение: можеш да минеш и с една група като направиш клас за плюсчето и минусчето, като по този начин спестяваш една референция следователно и ресурс:

Код: PHP
  1. $Template_Blank=preg_replace('/{{font}}([-+]?\d+)/', '<font size="$1">',$Template_Blank);

Това също е добър пример да видиш, че когато имаме метасимвол в клас (в случая "+") не е задължително да го ескейпваме,защото той губи своето специално значение и става едно обикновенно плюсче.
« Последна редакция: 11 Юни 2012, 18:20:01 от Stan »

georgirgeorgiev

  • Full Member
  • ***
  • Благодарности
  • -Казани: 77
  • -Получени: 13
  • Публикации: 164
Re: Регулярни изрази част 4
« Отговор #5 -: 25 Април 2015, 14:50:27 »
БОГ да ви благослови премного.

Благодаря Ви за урока. Благодаря Ви за възможността да научим това, което сте написали за регулярните изрази.