
Лабораторная №5
Тема: «Изучение регулярных выражений»
Цель: Изучить принцип работы с регулярными выражениями в JavaScript
Теоретические основы:
Регулярные выражения — это мощное средство для обработки входящих данных. Задача, требующая замены или поиска текста, может быть красиво решена с помощью этого "языка внутри языка". И хотя максимальный эффект от регулярных выражений можно добиться при использовании серверных языков, всё же не стоит недооценивать возможности этого приложения и на стороне клиента.
Примечание
Синтаксис регулярных выражений является достаточно сложным и его изучение требует серьёзных усилий. Наилучшим руководством по регулярным выражением на сегодняшний день является книга Дж. Фридла "Регулярные выражения", позволяющая, по словам автора, "научиться мыслить регулярными выражениями".
Основные понятия
Регулярное выражение (regular expression) — средство для обработки строк или последовательность символов, определяющая шаблон текста.
Модификатор — предназначен для "инструктирования" регулярного выражения.
Метасимволы — специальные символы, которые служат командами языка регулярных выражений.
Регулярное выражение задаётся как обычная переменная, только вместо кавычек используется слэш, например: var reg=/рег_выражение/
Под простейшими шаблонами будем понимать такие шаблоны, которые не нуждаются в каких-либо специальных символах.
Допустим, нашей задачей является замена всех букв "р" (малых и заглавных) на латинскую большую букву "R" в словосочетании Регулярные выражения.
Создаём шаблон var reg=/р/ и воспользуясь методом replace осуществляем задуманное:
<script language="JavaScript">
var str="Регулярные выражения"
var reg=/р/
var result=str.replace(reg, "R")
document.write(result)
</script>
В результате получим строку — РегуляRные выражения, замена произошла только на первом вхождении буквы "р" с учётом регистра.
Но под условия нашей задачи этот результат не подходит... Тут нам понадобятся модификаторы "g" и "i", которые могут использоваться как отдельно, так и совместно. Эти модификаторы ставятся в конце шаблона регулярного выражения, после слэша, и имеют следующие значения:
Модификатор "g" — задаёт поиск в строке как "глобальный", т.е. в нашем случае замена произойдет для всех вхождений буквы "р". Теперь шаблон выглядит так: var reg=/р/g, подставим его в наш код:
<script language="JavaScript">
var str="Регулярные выражения"
var reg=/р/g
var result=str.replace(reg, "R")
document.write(result)
</script>
получим строку — РегуляRные выRажения.
Модификатор "i" — задаёт поиск в строке без учёта регистра, добавив этот модификатор в наш шаблон var reg=/р/gi, после выполнения скрипта получим искомый результат нашей задачи — RегуляRные выRажения.
Специальные символы (метасимволы)
Метасимволы задают тип символов искомой строки, способ окружения искомой строки в тексте, а так же количество символов отдельного типа в просматриваемом тексте. Поэтому метасимволы можно разделить на три группы:
Метасимволы поиска совпадений.
Количественные метасимволы.
Метасимволы позиционирования.
Таблица 1. Метасимволы поиска совпадений
Символ |
Значение |
Описание |
Пример |
\b |
граница слова |
задаёт условие, при котором шаблон должен выполняться в начале или конце слова
|
/\ber/ совпадает с error, не совпадает с hero или с player /er / совпдает с player, не совпадает с hero или с error /\ber\b/ не совпадает с hero или с player или с error, может совпасть только с er |
\B |
не граница слова |
задаёт условие, при котором шаблон не выполняется в начале или конце слова
|
/\Ber/ совпадает с hero или с player, не совпадает с error /er\B/ совпадает с error или с player, не совпадает с hero /\Ber\B/ совпадает с hero, не совпадает с player или с error |
\d |
цифра от 0 до 9 |
- |
/\d\d\d\d/ совпадает с любым четырёхзначным числом |
\D |
не цифра |
- |
/\D\D\D\D/ не совпадёт с 2005 или 05.г или №126 и т.д. |
\s |
одиночный пустой символ |
соответствует символу пробела |
\over\sbyte\ совпадает только с over byte |
\S |
одиночный непустой символ |
любой один символ за исключением пробела |
\over\Sbyte\ совпадает с over-byte или с over_byte, не совпадает с over byte или over--byte |
\w |
буква, цифра или символ подчёркивания |
- |
/A\w/ совпадает с A1 или с AB, не совпадает с A+ |
\W |
не буква, цифра или символ подчёркивания |
- |
/A\W/ не совпадает с A1 или с AB, совпадает с A+ |
. |
любой символ |
любые знаки, буквы, цифры и т.д. |
/.../ совпадает с любыми тремя символами ABC или !@4 или 1 q |
[ ] |
набор символов |
задаёт условие, при котором шаблон должен выполняться при любом совпадении символов заключенных в квадратные скобки |
/[QA]WERTY/ совпадает с QWERTY, с AWERTY |
[^ ] |
набор не входящих символов |
задаёт условие, при котором шаблон не должен выполняться при любом совпадении символов заключенных в квадратные скобки |
/[^QA]WERTY/ не совпадает с QWERTY, с AWERTY |
Символы, приведенные в таблице "Метасимволы поиска совпадений" не надо путать с последовательностью знаков перехода используемых в строках, таких как \\t — табуляция, \\n - переход на новую строку и т.д.
Таблица 2. Количественные метасимволы
Символ |
Количество совпадений |
Пример |
* |
Ноль и большее количество раз |
/Ja*vaScript/ совпадает с JvaScript или с JaavaScript или с JaaavaScript, не совпадает с JovaScript |
? |
Ноль или один раз |
/Ja?vaScript/ совпадает только с JvaScript или с JavaScript |
+ |
Один и большее количество раз |
/Ja+vaScript/ совпадает с JavaScript или с JaavaScript или с JaaavaScript, не совпадает с JvaScript |
{n} |
точно n раз |
/Ja{2}vaScript/ совпадает только с JaavaScript |
{n,} |
n или большее количество раз |
/Ja{2,}vaScript/ совпадает с JaavaScript или с JaaavaScript, не совпадает с JvaScript или с JavaScript |
{n,m} |
по крайней мере, n раз, но не более чем m раз |
/Ja{2,3}vaScript/ совпадает только с JaavaScript или с JaaavaScript |
Каждый символ, приведенный в таблице "Количественные метасимволы" применяется к одному предшествующему символу или метасимволу в регулярном выражении.
Таблица 3. Метасимволы позиционирования
Символ |
Совпадает с расположением |
Пример |
^ |
в начале строки |
/^Fred/ совпадает с Fred is OK, не совпадает с I'm with Fred или с Is Fred here? |
$ |
в конце строки |
/Fred$/ совпадает с I'm with Fred, не совпадает с Fred is OK или с Is Fred here? |
Последний набор метасимволов предназначен для обозначения, где искать (если это важно) подстроку в начале строки или в конце.
Некоторые методы для работы с шаблонами
replace — данный метод мы уже использовали в самом начале статьи, он предназначен для поиска образца и замены найденной подстроки на новую подстроку.
test — данный метод проверяет, есть ли совпадения в строке относительно шаблона и возвращает false, если сопоставление с образцом закончилось неудачей, в противном случае true.
Например:
<script language="JavaScript">
var str="JavaScript"
var reg=/PHP/
var result=reg.test(str)
document.write(result)
</script>
выведет в качестве результата false, т.к. строка "JavaScript" не равна строке "PHP".
Также метод test может возвращать вместо true или false любую другую строку заданную программистом.
Например:
<script language="JavaScript">
var str="JavaScript"
var reg=/PHP/
var result=reg.test(str) ? "Строка совпала" : "Строка не совпала"
document.write(result)
</script>
в этом случае в качестве результата будет строка: Строка не совпала.
exec — данный метод выполняет сопоставление строки с образцом, заданным шаблоном. Если сопоставление с образцом закончилось неудачей, то возвращается значение null. В противном случае результатом является массив подстрок, соответствующих заданному образцу. /*Первый элемент массива будет равен исходной строке удовлетворяющее заданному шаблону*/
Например:
<script language="JavaScript">
var reg=/(\d+).(\d+).(\d+)/
var arr=reg.exec("Я родился 15.09.1980")
document.write("Дата рождения: ", arr[0], "< br>")
document.write("День рождения: ", arr[1], "< br>")
document.write("Месяц рождения: ", arr[2], "< br>")
document.write("Год рождения: ", arr[3], "< br>")
</script>
в результате получим четыре строки:
Дата рождения: 15.09.1980
День рождения: 15
Месяц рождения: 09
Год рождения: 1980
Задание:
Дополнить ранее выполненную лабораторную работу следующим функционалом:
при заполнении данных должны учитываться их тип (определённый в физической модели IDEF1x) и формат (например, наличие первой заглавной буквы, только символом кириллицы, количества нулей после запятой, запрет на пустую строку и т.д.);
возможность удалять и редактировать существующие в таблице записи1;
учёт связи по ключевым полям обязателен;
выделение неверно заполненного поля (например, изменением цвета подписи) и предоставление примера правильного заполнения.
Задачи:
Изучить подходы к реализации регулярных выражений (PECL, POSIX)
Изучить возможности JavaScript в реализации регулярных выражений
Изучить функции и свойства класса RegExp в JavaScript
Самостоятельно определять способ реализации функционала, связанного с добавлением, удалением или редактированием строк. Допускается выбор из подхода DOM, стандартного или смешанного
Структура отчёта:
1. Титульный
2. Содержание
3. Описание целей и задач
4. Описание системы
5. Файлы HTML и JavaScript
Пример лабораторной работы №5:
XML файл: остается без изменений
XSLT файл: описываем формы для удаления и замены значений в таблицах client и employee, добавляем скрипт с ограничениями для ввода данных.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<head>
<script>
function show(obj){
if(document.getElementById("sel").value==1){
document.form1.style.display='block';
document.form2.style.display='none'; }
if(document.getElementById("sel").value==2){
document.form2.style.display='block';
document.form1.style.display='none'; }}
function prname(){
var name_client = document.getElementById("name").value;
var text = /^[а-яА-Яa-zA-Z\s]+$/;
if (text.test(name_client) == true){
document.getElementById("name").style.color='green';
}
else{
document.getElementById("name").style.color='red' }}
function prbirth(){
var birth_client = document.getElementById("birth").value;
var text = /^[01-31.01-12.1970-1995]+$/;
if (text.test(birth_client) == true){
document.getElementById("birth").style.color='green';
}
else{
document.getElementById("birth").style.color='red' }}
function prIDcard(){
var IDcard_client = document.getElementById("IDcard").value;
var text = /^[0-9]{5}$/;
if (text.test(IDcard_client) == true){
document.getElementById("IDcard").style.color='green';
}
else{
document.getElementById("IDcard").style.color='red' }}
function prtelephone(){
var telephone_client = document.getElementById("telephone").value;
var text = /^[8][0-9]{9}$/;
if (text.test(telephone_client) == true){
document.getElementById("telephone").style.color='green';
}
else{
document.getElementById("telephone").style.color='red' }}
function provename(){
var ename_employee = document.getElementById("ename").value;
var text = /^[а-яА-Яa-zA-Z\s]+$/;
if (text.test(ename_employee) == true){
document.getElementById("ename").style.color='green';
}
else{
document.getElementById("ename").style.color='red' }}
function provposition(){
var position_employee = document.getElementById("position").value;
var text = /^[а-яА-Яa-zA-Z\s]+$/;
if (text.test(position_employee) == true){
document.getElementById("position").style.color='green';
}
else{
document.getElementById("position").style.color='red' }}
function provetelephone(){
var etelephone_employee = document.getElementById("etelephone").value;
var text = /^[8][0-9]{9}$/;
if (text.test(etelephone_employee) == true){
document.getElementById("etelephone").style.color='green';
}
else{
document.getElementById("etelephone").style.color='red' }}
function provemail(){
var email_employee = document.getElementById("email").value;
var text = /^[a-zа-я0-9\W]+$/;
if (text.test(email_employee) == true){
document.getElementById("email").style.color='green';
}
else{
document.getElementById("email").style.color='red' }}
</script>
<title>Fitness</title>
</head>
<body>
<select name="select" id="sel" onchange="show(this);">
<option value="1">client</option>
<option value="2">employee</option>
</select>
<form name="form1" method="post" action="client.php"
id="form1" style="display:block">
<input type="text" name="name" value="ФИО" id="name" onKeyDown="prname()"/>
<br/>
<input type="text" name="birth" value="Дата рождения" id="birth" onKeyDown="prbirth()"/><br/>
<input type="text" name="IDcard" value="№ карты" id="IDcard" onKeyDown="prIDcard()"/><br/>
<input type="text" name="telephone" value="Телефон" id="telephone" onKeyDown="prtelephone()"/><br/>
<input type="submit" name="submit"
value="Добавить запись"/>
</form>
<form name="form2" method="post" action="employee.php"
id="form2" style="display:none">
<input type="text" name="ename" value="ФИО" id="ename" onKeyDown="provename()"/> <br/>
<input type="text" name="position" value="Должность" id="position" onKeyDown="provposition()"/><br/>
<input type="text" name="etelephone" value="Телефон" id="etelephone" onKeyDown="provetelephone()"/><br/>
<input type="text" name="email" value="Электронная почта" id="email" onKeyDown="provemail()"/><br/>
<input type="submit" name="submit"
value="Добавить запись"/>
</form>
<h2>Client</h2>
<table border="1" id='client'>
<thead>
<tr bgcolor="purple" >
<th>№</th>
<th>name</th>
<th>birth</th>
<th>IDcard</th>
<th>telephone</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="fitness/list1/client">
<tr>
<xsl:if test="position() mod 2 = 1">
<xsl:attribute name="style">background-color: pink;</xsl:attribute>
</xsl:if>
<td>
<xsl:value-of select="position()"/>
</td>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="birth"/></td>
<td><xsl:value-of select="IDcard"/></td>
<td><xsl:value-of select="telephone"/></td>
</tr>
</xsl:for-each>
</tbody>
</table>
<p>Всего элементов: <xsl:value-of select="count(fitness/list1/client)"/></p>
Удаление строки:
<form name="form3" method="POST" action="delete.php">
<input type="text" name="del" id="del"/>
<br/>
<input type="submit" name="submit3" value="Удалить"/>
</form>
<h2>Employee</h2>
<table border="1">
<tr bgcolor="purple">
<th>№</th>
<th>name</th>
<th>position</th>
<th>telephone</th>
<th>email</th>
</tr>
<xsl:for-each select="fitness/list2/employee">
<tr>
<xsl:if test="position() mod 2 = 1">
<xsl:attribute name="style">background-color: pink;</xsl:attribute>
</xsl:if>
<td>
<xsl:value-of select="position()"/>
</td>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="position"/></td>
<td><xsl:value-of select="telephone"/></td>
<td><xsl:value-of select="email"/></td>
</tr>
</xsl:for-each>
</table>
<p>Всего элементов:<xsl:value-of select="count(fitness/list2/employee)"/></p>
<form name="form4" method="POST" action="edit.php">
Введите номер изменяемой строки:<br/>
<input type="text" name="edit" id="edit"/>
<br/>
Введите ФИО:<br/>
<input type="text" name="nameedit" id="nameedit"/>
<br/>
Введите должность:<br/>
<input type="text" name="posedit" id="posedit"/>
<br/>
Введите номер телефона:<br/>
<input type="text" name="teledit" id="teledit"/>
<br/>
Введите адрес электронной почты:<br/>
<input type="text" name="emailedit" id="emailedit"/>
<br/>
<input type="submit" name="submit4" value="Изменить"/>
</form>
<h2>Contract</h2>
<table border ="1">
<tr bgcolor="purple">
<th>IDcard</th>
<th>contract_date</th>
<th>term</th>
</tr>
<xsl:for-each select="fitness/list3/contract">
<tr>
<xsl:if test="position() mod 2 = 1">
<xsl:attribute name="style">background-color: pink;</xsl:attribute>
</xsl:if>
<td><xsl:value-of select="IDcard"/></td>
<td><xsl:value-of select="contract_date"/></td>
<td><xsl:value-of select="term"/></td>
</tr>
</xsl:for-each>
</table>
<p>Всего элементов: <xsl:value-of select="count(fitness/list3/contract)"/></p>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
PHP добавление client: остается без изменений
PHP добавление employee: остается без изменений
Рис. 6. Ограничение ввода данных
PHP удаление:
Описание: создается для того, чтобы обрабатывать и удалять данные, добавленные в форму client.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
</head>
<body>
<?php
$dom = new DOMDocument();
$dom->load('fit.xml');
$s = simplexml_import_dom($dom);
$ii=$_POST['del'];
$i=$ii-2;
unset($s->list1[$i]->client);
$dom->save('fit.xml');
?>
<meta http-equiv="refresh" content="0; url=fit.xml">
</body>
</html>
Рис. 7. Форма для удаления записи
PHP замена:
Описание: создается для того, чтобы обрабатывать и заменять данные, добавленные в форму employee.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
</head>
<body>
<?php
$dom = new DOMDocument();
$dom->load('fit.xml');
$s = simplexml_import_dom($dom);
$dd=$_POST['edit'];
$d=$dd-2;
$s->list2[$d]->employee->name= $_POST['nameedit'];
$s->list2[$d]->employee->position = $_POST['posedit'];
$s->list2[$d]->employee->telephone = $_POST['teledit'];
$s->list2[$d]->employee->email = $_POST['emailedit'];
$dom->save('fit.xml');
?>
<meta http-equiv="refresh" content="0; url=fit.xml">
</body>
</html>
Рис. 8. Форма для замены записи