Регулярные выражения php
Содержание:
- Введение в регулярные выражения
- Введение в регулярные выражения
- Что сейчас востребовано, доступно для декретниц и приносит доход?
- Примеры preg_replace PHP
- JavaScript
- Примеры регулярных выражений
- Нечёткие регулярные выражения
- Как выглядят регулярные выражения¶
- Обработка и замена при помощи «preg_replace_callback»
- Брокер — это не навсегда. Не понравится — найдете другого
- Границы
- Клей из пенопласта и растворителя своими руками
- Функции для работы с регулярными выражениями
- Короткие обозначения
- Запрет возврата
- Строковые методы, поиск и замена
- Количество {n}
- Выбираем устройство загрузки
- Задачка на проверку телефонов
- Регулярные выражения и Unicode¶
- Заключение
Введение в регулярные выражения
Регулярные выражения, также называемые regex, используются практически во всех языках программирования. В python они реализованы в стандартном модуле .
Он широко используется в естественной обработке языка, веб-приложениях, требующих проверки ввода текста (например, адреса электронной почты) и почти во всех проектах в области анализа данных, которые включают в себя интеллектуальную обработку текста.
Эта статья разделена на 2 части.
Прежде чем перейти к синтаксису регулярных выражений, для начала вам лучше понять, как работает модуль .
Итак, сначала вы познакомитесь с 5 основными функциями модуля , а затем посмотрите, как создавать регулярные выражения в python.
Узнаете, как построить практически любой текстовый шаблон, который вам, скорее всего, понадобится при работе над проектами, связанными с поиском текста.
Введение в регулярные выражения
Регулярные выражения (RegExp) — это очень эффективный способ работы со строками.
Составив регулярное выражение с помощью специального синтаксиса вы можете:
- искать текст в строке
- заменять подстроки в строке
- извлекать информацию из строки
Почти во всех языках программирования есть регулярные выражения. Есть небольшие различия в реализации, но общие концепции применяются практически везде.
Регулярные выражения относятся к 1950-м годам, когда они были формализованы как концептуальный шаблон поиска для алгоритмов обработки строк.
Регулярные выражения реализованные в UNIX, таких как grep, sed и популярных текстовых редакторах, начали набирать популярность и были добавлены в язык программирования Perl, а позже и в множество других языков.
JavaScript, наряду с Perl, это один из языков программирования в котором поддержка регулярных выражений встроена непосредственно в язык.
Что сейчас востребовано, доступно для декретниц и приносит доход?
На сегодняшний день очень востребована и хорошо оплачиваема работа в сфере интернет-маркетинга:
Существует масса курсов удаленного обучения по этим профессиям. Если денег на платное образование нет, можете попробовать заработать деньги с помощью сервиса Workle или Яндекс.Толока.
В первом случае вы сможете удаленно работать менеджером по туризму, страховым агентом, кредитным специалистом или представителем сотовых операторов. В случае с Яндекс.Толокой вам необходимо будет выполнять за вознаграждения различные несложные задания. Правда, и оплата будет соответствующей.
Кстати, вы также можете через интернет оказывать какие-либо услуги, которые были связаны со спецификой вашей работы до декрета, например, бухгалтерские, юридические, педагогические (репетиторство) и так далее. Еще больше идей для заработка в декрете вы можете почерпнуть в статьях, расположенных на моем сайте в разделе «Бизнес-мама».
Примеры preg_replace PHP
1.
$text = preg_replace("~<a href=\"http://www\.aaa\">+?</a>~",'',$text);
2.
$text = preg_replace('#<!--.*-->#sUi', '', $text);
3.
$text = preg_replace ("~(\\\|\*|\?|\|\(|\\\$|\))~", "",$text);
4.
$text = preg_replace('/(<(+)>)/U', '', $text);
5.
$text = preg_replace('#<script*>.*?</script>#is', '', $text);
6.
$text = str_replace('#39;', '', $text); // удаляем одинарные кавычки $text = str_replace('"', '', $text); // удаляем двойные кавычки $text = str_replace('&', '', $text); // удаляем амперсанд $text = preg_replace('/(()_—«»#\/]+)/', '', $text); // удаляем недоспустимые символы
7.
$text = trim($text); // удаляем пробелы по бокам $text = preg_replace('/ /', '', $text); // чистим обычные пробелы $text = preg_replace("/ +/", " ", $text); // множественные пробелы заменяем на одинарные
8.
$text = preg_replace("/(\r\n){3,}/", "\r\n\r\n", $text); // убираем лишние переводы строк (больше 1 строки)
9.
$file = 'image.jpg'; $file = preg_replace("/.*?\./", '', $file); // выведет image
10.
function ProcessText($text) { $text = trim($text); // удаляем пробелы по бокам $text = stripslashes($text); // удаляем слэши $text = htmlspecialchars($text); // переводим HTML в текст $text = preg_replace("/ +/", " ", $text); // множественные пробелы заменяем на одинарные $text = preg_replace("/(\r\n){3,}/", "\r\n\r\n", $text); // убираем лишние переводы строк (больше 1 строки) $test = nl2br ($text); // заменяем переводы строк на тег $text = preg_replace("/^\"(+)\"/u", "$1«$2»", $text); // ставим людские кавычки $text = preg_replace("/(«){2,}/","«",$text); // убираем лишние левые кавычки (больше 1 кавычки) $text = preg_replace("/(»){2,}/","»",$text); // убираем лишние правые кавычки (больше 1 кавычки) $text = preg_replace("/(\r\n){2,}/u", "</p><p />", $text); // ставим абзацы return $text; //возвращаем переменную }
11.
$string = preg_replace("!<title>(.*?)</title>!si","<НОВЫЙ_ТЕГ>\\1</НОВЫЙ_ТЕГ>",$string);
12.
$text = preg_replace('#(\.|\?|!|\(|\)){3,}#', '\1\1\1', $text);
13.
$string = preg_replace("/^/", "Начало: ", $string); // в начало $string = preg_replace("/$/", " читать далее...", $string); // в конец
14.
$text = preg_replace('#(?<!\])\bhttp://+#i', "<a href=\"$0\" target=_blank><u>Посмотреть на сайте</u></a>", nl2br(stripslashes($text)));
15.
$str = preg_replace('/^(.+?)(\?.*?)?(#.*)?$/', '$1$3', $url);
16.
$string = preg_replace("/^/", " ", $string); // в начало всех строк $string = preg_replace("/$/", " ", $string); // в конец всех строк
17.
// $document на выходе должен содержать HTML-документ. // Необходимо удалить все HTML-теги, секции javascript, // пробельные символы. Также необходимо заменить некоторые // HTML-сущности на их эквивалент. $search = array ("'<script*?>.*?</script>'si", // Вырезает javaScript "'<[\/\!]*?*?>'si", // Вырезает HTML-теги "'()+'", // Вырезает пробельные символы "'&(quot|#34);'i", // Заменяет HTML-сущности "'&(amp|#38);'i", "'&(lt|#60);'i", "'&(gt|#62);'i", "'&(nbsp|#160);'i", "'&(iexcl|#161);'i", "'&(cent|#162);'i", "'&(pound|#163);'i", "'&(copy|#169);'i", "'&#(\d+);'e"); // интерпретировать как php-код $replace = array ("", "", "\\1", "\"", "&", "<", ">", " ", chr(161), chr(162), chr(163), chr(169), "chr(\\1)"); $text = preg_replace($search, $replace, $document);
18.
$html = preg_replace( '/(\S+)@(+)/is', '<a href="mailto:$0">$0</a>', $text);
JavaScript
JS Array
concat()
constructor
copyWithin()
entries()
every()
fill()
filter()
find()
findIndex()
forEach()
from()
includes()
indexOf()
isArray()
join()
keys()
length
lastIndexOf()
map()
pop()
prototype
push()
reduce()
reduceRight()
reverse()
shift()
slice()
some()
sort()
splice()
toString()
unshift()
valueOf()
JS Boolean
constructor
prototype
toString()
valueOf()
JS Classes
constructor()
extends
static
super
JS Date
constructor
getDate()
getDay()
getFullYear()
getHours()
getMilliseconds()
getMinutes()
getMonth()
getSeconds()
getTime()
getTimezoneOffset()
getUTCDate()
getUTCDay()
getUTCFullYear()
getUTCHours()
getUTCMilliseconds()
getUTCMinutes()
getUTCMonth()
getUTCSeconds()
now()
parse()
prototype
setDate()
setFullYear()
setHours()
setMilliseconds()
setMinutes()
setMonth()
setSeconds()
setTime()
setUTCDate()
setUTCFullYear()
setUTCHours()
setUTCMilliseconds()
setUTCMinutes()
setUTCMonth()
setUTCSeconds()
toDateString()
toISOString()
toJSON()
toLocaleDateString()
toLocaleTimeString()
toLocaleString()
toString()
toTimeString()
toUTCString()
UTC()
valueOf()
JS Error
name
message
JS Global
decodeURI()
decodeURIComponent()
encodeURI()
encodeURIComponent()
escape()
eval()
Infinity
isFinite()
isNaN()
NaN
Number()
parseFloat()
parseInt()
String()
undefined
unescape()
JS JSON
parse()
stringify()
JS Math
abs()
acos()
acosh()
asin()
asinh()
atan()
atan2()
atanh()
cbrt()
ceil()
clz32()
cos()
cosh()
E
exp()
expm1()
floor()
fround()
LN2
LN10
log()
log10()
log1p()
log2()
LOG2E
LOG10E
max()
min()
PI
pow()
random()
round()
sign()
sin()
sqrt()
SQRT1_2
SQRT2
tan()
tanh()
trunc()
JS Number
constructor
isFinite()
isInteger()
isNaN()
isSafeInteger()
MAX_VALUE
MIN_VALUE
NEGATIVE_INFINITY
NaN
POSITIVE_INFINITY
prototype
toExponential()
toFixed()
toLocaleString()
toPrecision()
toString()
valueOf()
JS OperatorsJS RegExp
constructor
compile()
exec()
g
global
i
ignoreCase
lastIndex
m
multiline
n+
n*
n?
n{X}
n{X,Y}
n{X,}
n$
^n
?=n
?!n
source
test()
toString()
(x|y)
.
\w
\W
\d
\D
\s
\S
\b
\B
\0
\n
\f
\r
\t
\v
\xxx
\xdd
\uxxxx
JS Statements
break
class
continue
debugger
do…while
for
for…in
for…of
function
if…else
return
switch
throw
try…catch
var
while
JS String
charAt()
charCodeAt()
concat()
constructor
endsWith()
fromCharCode()
includes()
indexOf()
lastIndexOf()
length
localeCompare()
match()
prototype
repeat()
replace()
search()
slice()
split()
startsWith()
substr()
substring()
toLocaleLowerCase()
toLocaleUpperCase()
toLowerCase()
toString()
toUpperCase()
trim()
valueOf()
Примеры регулярных выражений
Любой символ кроме новой строки
Точки в строке
Любая цифра
Все, кроме цифры
Любая буква или цифра
Все, кроме букв и цифр
Только буквы
Соответствие заданное количество раз
1 и более вхождений
Любое количество вхождений (0 или более раз)
0 или 1 вхождение
Граница слова
Границы слов обычно используются для обнаружения и сопоставления началу или концу слова. То есть, одна сторона является символом слова, а другая сторона является пробелом и наоборот.
Например, регулярное выражение совпадает с ‘toy’ в ‘toy cat’, но не в ‘tolstoy’. Для того, чтобы ‘toy’ соответствовало ‘tolstoy’, используйте .
Можете ли вы придумать регулярное выражение, которое будет соответствовать только первой ‘toy’в ‘play toy broke toys’? (подсказка: с обеих сторон)
Аналогично, будет соответствовать любому non-boundary( без границ).
Например, будет соответствовать ‘toy’, окруженной словами с обеих сторон, как в ‘antoynet’.
Нечёткие регулярные выражения
В некоторых случаях регулярные выражения удобно применить для анализа текстовых фрагментов на естественном языке, то есть написанных людьми, и, возможно, содержащих опечатки либо нестандартные варианты употреблений слов. Например, если проводить опрос (допустим, на веб-сайте) «какой станцией метро вы пользуетесь», может оказаться, что «Невский проспект» посетители могут указать как:
- Невский
- Невск. просп.
- Нев. проспект
- наб. Канала Грибоедова («Канал Грибоедова» — это название второго выхода ст. м. Невский проспект)
Здесь обычные регулярные выражения неприменимы, в первую очередь из-за того, что входящие в образцы слова могут совпадать не очень точно (нечётко), но, тем не менее, было бы удобно описывать регулярными выражениями структурные зависимости между элементами образца,
например, в нашем случае, указать, что совпадение может быть с образцом «Невский проспект» ИЛИ «Канал Грибоедова», притом «проспект» может быть сокращено до «пр» или отсутствовать, а перед «Канал» может находиться сокращение «наб.»
Эта задача сродни полнотекстовому поиску, отличаясь в том, что здесь короткий фрагмент должен сравниваться с набором образцов, а при полнотекстовом поиске, наоборот, образец обычно один, в то время как фрагмент текста очень большой, или задаче разрешения лексической многозначности, которая, однако, не позволяет задать структурирующие отношения между элементами образца.
Существует небольшое количество библиотек, реализующих механизм регулярных выражений с возможностью нечёткого сравнения:
- TRE — бесплатная библиотека на С, использующая синтаксис регулярных выражений, похожий на POSIX (стабильный проект);
- FREJ — open-source библиотека на Java, использующая Lisp-образный синтаксис и лишённая многих возможностей обычных регулярных выражений, но сосредоточенная на различного рода автоматических заменах фрагментов текста (бета-версия).
Как выглядят регулярные выражения¶
В JavaScript регулярные выражения это объект, который может быть определён двумя способами.
Первый способ заключается в создании нового объекта RegExp с помощью конструктора:
Второй способ заключается в использовании литералов регулярных выражений:
Вы знаете что в JavaScript есть литералы объектов и литералы массивов? В нём также есть литералы regexp.
В приведённом выше примере называется шаблоном. В литеральной форме он находится между двумя слэшами, а в случае с конструктором объекта, нет.
Это первое важное отличие между двумя способами определения регулярных выражений, остальные мы увидим позже
Обработка и замена при помощи «preg_replace_callback»
Переходим к самому интересному. Если нужно над найденным фрагметом произвести какие-то действия и только потом осуществить замену, то следует использовать «preg_replace_callback». Рассмотрим как с помощью этой функции в именах сделать первую букву заглавной.
<html> <head> <meta charset="utf-8"> </head> <body> <?php $sContent = "<xx>наташа</xx> ... <xx>даша</xx> ... <xx>настя</xx>"; echo htmlspecialchars($sContent); echo "<br />"; $sContent = preg_replace_callback('|(<xx>)(.+)(</xx>)|iU', function($matches){ $matches = mb_substr(mb_strtoupper($matches, 'UTF-8'),0,1,'UTF-8').substr($matches, 2); return $matches.$matches.$matches; } ,$sContent); echo htmlspecialchars($sContent); ?> </body> </html>
В качестве параметров передаём маску поиска, функцию с кодом обработки и строковую переменную в которой осуществляем поиск. Дополнительно могут ещё быть заданы два необязательных параметра. О них в следующем разделе статьи.
Переменная «$matches» это массив, содержащий элементы регулярного выражения. В нулевом элементе будет содержаться вся исходная строка, а в остальных — содержимое скобок.
Код обработки не описываю, но отмечу что для замены первой буквы на заглавную я использую PHP функции для работы со строками в UTF-8 кодировке. Если у Вас кодировка cp1251, то нужно отбросить префикс «mb_» и удалить последний параметр у функций.
ВНИМАНИЕ! Код в примере будет работать только при использовании PHP версии 5.3 и выше. Для более поздних версий требуется доработка
Брокер — это не навсегда. Не понравится — найдете другого
Границы
Java Regex API также может соответствовать границам в строке, а именно началом или концом строки, началом слова и т. д. API Java Regex поддерживает следующие границы:
Символ | Описание |
---|---|
^ | Начало строки |
$ | Конец строки |
\b | Граница слова (где слово начинается или заканчивается, например, пробел, табуляция и т. д.). |
\B | Несловесная граница |
\A | Начало ввода. |
\G | Конец предыдущего совпадения |
\Z | Конец ввода, кроме конечного объекта (если есть) |
\z |
Начало строки
Соответствие границ ^ соответствует началу строки в соответствии со спецификацией API Java. Например, следующий пример получает только одно совпадение с индексом 0:
String text = "Line 1\nLine2\nLine3"; Pattern pattern = Pattern.compile("^"); Matcher matcher = pattern.matcher(text); while(matcher.find()){ System.out.println("Found match at: " + matcher.start() + " to " + matcher.end()); }
Даже если входная строка содержит несколько разрывов строк, символ ^ соответствует только началу входной строки, а не началу каждой строки (после каждого переноса строки).
Начало соответствия строки / строки часто используется в сочетании с другими символами, чтобы проверить, начинается ли строка с определенной подстроки. Например, этот пример проверяет, начинается ли строка ввода с подстроки http: //:
String text = "http://jenkov.com"; Pattern pattern = Pattern.compile("^http://"); Matcher matcher = pattern.matcher(text); while(matcher.find()){ System.out.println("Found match at: " + matcher.start() + " to " + matcher.end()); }
В этом примере найдено одно совпадение подстроки http: // из индекса 0 в индекс 7 во входном потоке. Даже если бы входная строка содержала больше экземпляров подстроки http: //, они не соответствовали бы этому регулярному выражению, так как оно начиналось с символа ^.
Конец строки
Соответствие $ соответствует концу строки в соответствии со спецификацией Java. На практике, однако, похоже, что он соответствует только концу входной строки.
Соответствие начала строки часто используется в сочетании с другими символами, чаще всего для проверки, заканчивается ли строка определенной подстрокой:
String text = "http://jenkov.com"; Pattern pattern = Pattern.compile(".com$"); Matcher matcher = pattern.matcher(text); while(matcher.find()){ System.out.println("Found match at: " + matcher.start() + " to " + matcher.end()); }
В этом примере будет найдено одно совпадение в конце входной строки.
Клей из пенопласта и растворителя своими руками
Первый вариант получения клеевого раствора заключается в растворении кусков пенопласта в разбавителе. Разбавителем можно использовать бензин. Способов изготовления клеевого раствора несколько, различие в основном в видах материалов, которые будут использоваться, как компоненты состава.
Подобный клей из пенопласта своими руками позволяет получить прочное соединение при ремонтных работах на крыше, возможно применения как соединяющего вещества стыковочных мест во время кровельных работ. Высохнув состав становиться похож на стекло.
Второй метод создания пенопластового вещества для склеивания материалов, заключается в распределение мелких частей пенопласта по месту, где нужно склеить детали, после этого пенопластовые части поливаются растворителем, в итоге части начинают растворяться, материал заполняет все трещинки и равномерно закрывает имеющиеся зазоры.
Подобный клей из пенопласта своими руками позволяет получить прочное соединение при ремонтных работах.
Особенности самодельного клея, где может применяться
Прежде, чем растворить пенопласт до жидкого состояния, нужно изучить особенности работы с компонентами, иначе можно получить неудовлетворительный результат. Отмечают следующие правила:
- Работать необходимо, соблюдая меры безопасности, чтобы не получить проблем со здоровьем;
- Нельзя заниматься изготовлением и поклейкой вблизи открытых источников огня, вещества воспламеняющиеся, поэтому подобное соседство опасно;
- Получившееся средство следует хорошо размешивать, чтобы клеевые характеристики получились надежными;
- Средство может применяться, как защитное покрытие, тогда готовят более жидкий раствор;
- Отвердение покрытия происходит через несколько дней, количество их зависит от толщины слоя.
В бытовых условиях состав может использоваться для разных целей. Среди них выделяются склеивание карнизов на потолке, фиксация половых плинтусов, ремонта различных деталей мебели, установка экструдированного пенополистирола. Может применяться вместо казеинового и столярного клеевого раствора. Получившийся шов сохраняет свои свойства около полутора лет.
Получившееся средство следует хорошо размешивать, чтобы клеевые характеристики получились надежными.
Функции для работы с регулярными выражениями
В PHP есть поддержка 2 типов записи РВ — POSIX и Perl. POSIX (Portable Operating System Interface) представляет собой интерфейс переносной операционной системы и стандарт для интерфейсов приложений. Сейчас мы рассмотрим РВ POSIX и Perl-совместимые РВ.
Скорость выполнения функций для работы с РВ ниже строковых функций, которые обладают аналогичными возможностями. По этой причине лучше использовать строковые функции — если, конечно, ущерба эффективности не наносится.
ereg()
bool ereg(string pattern, string string )
Эта функция осуществляет поиск соответствия РВ в строке string, который задан в шаблоне pattern. В случае наличия соответствий шаблона с подвыражениями их сохранят в массиве соответствий regs. В $regs имеется копия строки string, а в $regs находится подстрока, которая начинается с первой левой скобки. Подстрока со второй левой скобки хранится в $regs и т. д.
Рассмотрим код, который из формата YYYY-MM-DD преобразовывает формат даты в DD.MM.YYYY.
<? $date = "2015-03-21"; if (ereg ("({4})-({1,2})-({1,2})", $date, $regs)){ echo "$regs.$regs.$regs"; } else{ echo "Неверный формат даты: $date"; } ?>
ereg_replace()
string ereg_replace(string pattern, string replacement, string string)
Данная функция меняет шаблон pattern, который был обнаружен в строке string, на строку replacement. При наличии соответствия происходит осуществление модифицированной строки.
Будьте внимательны: указание числа как типа, который отличен от строкового, является ошибкой — число должно всегда указываться как строка.
<? $number = "1952"; $str = "Он родился в пятьдесят втором."; echo("до замены:$str"); $str = ereg_replace("пятьдесят втором", $number, $str); echo("<br> после замены: $str"); ?>
Результат:
до замены: Он родился в пятьдесят втором.после замены: Он родился в 1952.
eregi()
bool eregi (string pattern, string string)
Данная функция аналогична ereg. Отличие состоит в том, что регистр игнорируется.
eregi_replace()
string eregi_replace (string pattern, string replacement, string string)
Отличие данной функции от ereg_replace состоит в том, что она не является чувствительной к регистру.
split()
array split (string pattern, string string )
Данная функция проводит возвращение массива строк из подстрок строк string, которые были образованы в соответствии с РВ pattern в ходе разделения строки string на подстроки. При указании параметра limit (он не является обязательным) возвращаемый массив будет иметь до limit элементов, причем в последнем имеется неразделенная часть строки.
Данная функция окажет пользу при разделении доменных имен, дат и проч. Например:
<? $url = "www.softtime.ru"; $array = split ("\.", $url); foreach($array as $index => $val) { echo("$index -> $val <br />"); }?>
В результате будет следующее:
0 -> www 1 -> softtime 2 -> ru
Это же можно осуществить и с датой:
<? $date = "10-12-2003" $array = split ("-", $date); foreach($array as $index => $val){ echo("$index -> $val <br />"); } ?>
В результате мы получим:
0 -> 10 1 -> 12 2 -> 2015
spliti()
array spliti (string pattern, string string )
Короткие обозначения
Для самых востребованных квантификаторов есть сокращённые формы записи:
-
Означает «один или более». То же самое, что и .
Например, находит числа (из одной или более цифр):
-
Означает «ноль или один». То же самое, что и . По сути, делает символ необязательным.
Например, шаблон найдёт после которого, возможно, следует , а затем .
Поэтому шаблон найдёт два варианта: и :
-
Означает «ноль или более». То же самое, что и . То есть символ может повторяться много раз или вообще отсутствовать.
Например, шаблон находит цифру и все нули за ней (их может быть много или ни одного):
Сравните это с (один или более):
Запрет возврата
Переписывать регулярное выражение не всегда удобно, и не всегда очевидно, как это сделать.
Альтернативный подход заключается в том, чтобы запретить возврат для квантификатора.
Движок регулярных выражений проверяет множество вариантов, которые для человека являются очевидно ошибочными.
Например, в шаблоне для человека очевидно, что в не нужно «откатывать» . От того, что вместо одного у нас будет два независимых , ничего не изменится:
Если говорить об изначальном примере , то хорошо бы исключить возврат для . То есть, для нужно искать только одно слово целиком, максимально возможной длины. Не нужно уменьшать количество повторений , пробовать разбить слово на два , и т.п.
В современных регулярных выражениях для решения этой проблемы придумали захватывающие (possessive) квантификаторы, которые такие же как жадные, но не делают возврат (то есть, по сути, они даже проще, чем жадные).
Также есть «атомарные скобочные группы» – средство, запрещающее возврат внутри скобок.
К сожалению, в JavaScript они не поддерживаются, но есть другое средство.
Мы можем исключить возврат с помощью опережающей проверки.
Шаблон, захватывающий максимальное количество повторений без возврата, выглядит так: .
Расшифруем его:
- Опережающая проверка ищет максимальное количество , доступных с текущей позиции.
- Содержимое скобок вокруг не запоминается движком, поэтому оборачиваем внутри в дополнительные скобки, чтобы движок регулярных выражений запомнил их содержимое.
- …И чтобы далее в шаблоне на него сослаться обратной ссылкой .
То есть, мы смотрим вперед – и если там есть слово , то ищем его же .
Зачем? Всё дело в том, что опережающая проверка находит слово целиком, и мы захватываем его в шаблон посредством . Поэтому мы реализовали, по сути, захватывающий квантификатор . Такой шаблон захватывает только полностью слово , не его часть.
Например, в слове он не может захватить только , и оставить для совпадения с остатком шаблона.
Вот, посмотрите, сравнение двух шаблонов:
- В первом варианте сначала забирает слово целиком, потом постепенно отступает, чтобы попробовать найти оставшуюся часть шаблона, и в конце концов находит (при этом будет соответствовать ).
- Во втором варианте осуществляет опережающую проверку и видит сразу слово , которое целиком захватывает в совпадение, так что уже нет возможности найти .
Внутрь можно вместо вставить и более сложное регулярное выражение, при поиске которого квантификатор не должен делать возврат.
Больше о связи захватывающих квантификаторов и опережающей проверки вы можете найти в статьях Regex: Emulate Atomic Grouping (and Possessive Quantifiers) with LookAhead и Mimicking Atomic Groups.
Перепишем исходный пример, используя опережающую проверку для запрета возврата:
Здесь внутри скобок стоит вместо , так как есть ещё внешние скобки. Чтобы избежать путаницы с номерами скобок, можно дать скобкам имя, например .
Проблему, которой была посвящена эта глава, называют «катастрофический возврат» (catastrophic backtracking).
Мы разобрали два способа её решения:
- Уменьшение возможных комбинаций переписыванием шаблона.
- Запрет возврата.
Строковые методы, поиск и замена
Следующие методы работают с регулярными выражениями из строк.
Все методы, кроме replace, можно вызывать как с объектами типа regexp в аргументах, так и со строками, которые автоматом преобразуются в объекты RegExp.
Так что вызовы эквивалентны:
var i = str.search(/\s/) var i = str.search("\\s")
При использовании кавычек нужно дублировать \ и нет возможности указать флаги. Если регулярное выражение уже задано строкой, то бывает удобна и полная форма
var regText = "\\s" var i = str.search(new RegExp(regText, "g"))
Возвращает индекс регулярного выражения в строке, или -1.
Если Вы хотите знать, подходит ли строка под регулярное выражение, используйте метод (аналогично RegExp-методы ). Чтобы получить больше информации, используйте более медленный метод (аналогичный методу ).
Этот пример выводит сообщение, в зависимости от того, подходит ли строка под регулярное выражение.
function testinput(re, str){ if (str.search(re) != -1) midstring = " contains "; else midstring = " does not contain "; document.write (str + midstring + re.source); }
Если в regexp нет флага , то возвращает тот же результат, что .
Если в regexp есть флаг , то возвращает массив со всеми совпадениями.
Чтобы просто узнать, подходит ли строка под регулярное выражение , используйте .
Если Вы хотите получить первый результат — попробуйте r.
В следующем примере используется, чтобы найти «Chapter», за которой следует 1 или более цифр, а затем цифры, разделенные точкой. В регулярном выражении есть флаг , так что регистр будет игнорироваться.
str = "For more information, see Chapter 3.4.5.1"; re = /chapter (\d+(\.\d)*)/i; found = str.match(re); alert(found);
Скрипт выдаст массив из совпадений:
- Chapter 3.4.5.1 — полностью совпавшая строка
- 3.4.5.1 — первая скобка
- .1 — внутренняя скобка
Следующий пример демонстрирует использование флагов глобального и регистронезависимого поиска с . Будут найдены все буквы от А до Е и от а до е, каждая — в отдельном элементе массива.
var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; var regexp = //gi; var matches = str.match(regexp); document.write(matches); // matches =
Метод replace может заменять вхождения регулярного выражения не только на строку, но и на результат выполнения функции. Его полный синтаксис — такой:
var newString = str.replace(regexp/substr, newSubStr/function)
- Объект RegExp. Его вхождения будут заменены на значение, которое вернет параметр номер 2
- Строка, которая будет заменена на .
- Строка, которая заменяет подстроку из аргумента номер 1.
- Функция, которая может быть вызвана для генерации новой подстроки (чтобы подставить ее вместо подстроки, полученной из аргумента 1).
Метод не меняет строку, на которой вызван, а просто возвращает новую, измененную строку.
Чтобы осуществить глобальную замену, включите в регулярное выражение флаг .
Если первый аргумент — строка, то она не преобразуется в регулярное выражение, так что, например,
var ab = "a b".replace("\\s","..") // = "a b"
Вызов replace оставил строку без изменения, т.к искал не регулярное выражение , а строку «\s».
В строке замены могут быть такие спецсимволы:
Pattern | Inserts |
Вставляет «$». | |
Вставляет найденную подстроку. | |
Вставляет часть строки, которая предшествует найденному вхождению. | |
Вставляет часть строки, которая идет после найденного вхождения. | |
or | Где или — десятичные цифры, вставляет подстроку вхождения, запомненную -й вложенной скобкой, если первый аргумент — объект RegExp. |
Если Вы указываете вторым параметром функцию, то она выполняется при каждом совпадении.
В функции можно динамически генерировать и возвращать строку подстановки.
Первый параметр функции — найденная подстрока. Если первым аргументом является объект , то следующие параметров содержат совпадения из вложенных скобок. Последние два параметра — позиция в строке, на которой произошло совпадение и сама строка.
Например, следующий вызов возвратит XXzzzz — XX , zzzz.
function replacer(str, p1, p2, offset, s) { return str + " - " + p1 + " , " + p2; } var newString = "XXzzzz".replace(/(X*)(z*)/, replacer)
Как видите, тут две скобки в регулярном выражении, и потому в функции два параметра , .
Если бы были три скобки, то в функцию пришлось бы добавить параметр .
Следующая функция заменяет слова типа на :
function styleHyphenFormat(propertyName) { function upperToHyphenLower(match) { return '-' + match.toLowerCase(); } return propertyName.replace(//, upperToHyphenLower); }
Количество {n}
Самый простой квантификатор — это число в фигурных скобках: .
Он добавляется к символу (или символьному классу, или набору и т.д.) и указывает, сколько их нам нужно.
Можно по-разному указать количество, например:
- Точное количество:
-
Шаблон обозначает ровно 5 цифр, он эквивалентен .
Следующий пример находит пятизначное число:
Мы можем добавить , чтобы исключить числа длиннее: .
- Диапазон: , от 3 до 5
-
Для того, чтобы найти числа от 3 до 5 цифр, мы можем указать границы в фигурных скобках:
Верхнюю границу можно не указывать.
Тогда шаблон найдёт последовательность чисел длиной и более цифр:
Давайте вернёмся к строке .
Число – это последовательность из одной или более цифр. Поэтому шаблон будет :
Выбираем устройство загрузки
Задачка на проверку телефонов
Задачу надо проверить на большом числе телефонов,
чтобы убедиться что твой код правильный. Для этого давай добавим в программу
тесты, чтобы сразу было видно, верно все работает или нет.
Сделай 2 списка номеров (правильные и нет), добавь их в программу и напиши цикл,
который их по очереди прогоняет через регулярку и проверяет,
что они определяются как надо (если нет — надо вывести, какой именно номер
не распознается правильно).
Вот список номеров:
// Правильные: $correctNumbers = ; // Неправильные: $incorrectNumbers = [ '02', '84951234567 позвать люсю', '849512345', '849512345678', '8 (409) 123-123-123', '7900123467', '5005005001', '8888-8888-88', '84951a234567', '8495123456a', '+1 234 5678901', /* неверный код страны */ '+8 234 5678901', /* либо 8 либо +7 */ '7 234 5678901' /* нет + */ ];
Подсказка: не надо строить сложных выражений и предусматривать все
возможные комбинации символов. Достаточно написать:
Регулярные выражения и Unicode¶
Флаг является обязательным при работе с Unicode строками, в частности когда может понадобится обрабатывать строки в астральных плоскостях, которые не включены в первые 1600 символов Unicode.
Например эмодзи, но и только они.
Если вы не добавили этот флаг, то это просто регулярное выражение, которые должно найти совпадение одного символа, не будет работать, потому что для JavaScript этот эмодзи внутри представлен двумя символами:
Поэтому, всегда используйте флаг .
Unicode, как и обычные символы, может обрабатывать диапазоны:
JavaScript проверяет внутренние коды представления, поэтому на самом деле . Посмотрите полный список эмодзи чтобы увидеть коды и узнать их порядок.
Заключение
В предыдущих статьях, были рассмотрены основы регулярных выражений, а также некоторые более сложные выражения, которые могут оказаться полезными. В следующих двух статьях объясняется, как разные символы или последовательности символов работают в регулярных выражениях.
Если после прочтения приведённых выше статей вы все еще путаетесь в регулярных выражениях, советуем вам продолжить практиковаться на примерах того, как другие люди придумывают регулярные выражения.
Оригинал статьи: https://code.tutsplus.com/tutorials/a-simple-regex-cheat-sheet—cms-31278/
Перевод: Земсков Матвей