Проверить формат varchar. my SQL
Привет помогите пож. закончить функцию. (С. ниже)
Чем проверить Номер Рейса (Варчар)? Он может быть мин. 3 и мах. 8 знаков. Я уже это проверерила в Функции.
drop function if exists validate_flight_number;
DELIMITER $$
CREATE FUNCTION validate_flight_number (fln varchar(8))RETURNS int
BEGIN DECLARE result_c int;
IF char_length(fln) >= 3
and char_length(fln) <= 8
and ??????????
THEN SET result_c = 1;
ELSE set result_c = 0 ;
END IF;
RETURN result_c;
END$$
DELIMITER ;
Но не могу придумать как проверить следующие условия (вместо ?????????):
Эта сволочь не работает как надо((((((((
{}
x{n}
and x{m,n}
This notation is used to match many instances of the x
. In the case of x{n}
the match must be exactly that many times. In the case of x{m,n}
, the match can occur from m
to n
times. For example, to match zero or one instance of the string ari
(which is identical to (ari)?
), the following can be used:
SELECT 'Maria' REGEXP '(ari){0,1}'; +-----------------------------+ | 'Maria' REGEXP '(ari){0,1}' | +-----------------------------+ | 1 | +-----------------------------+
Почему вы так думаете? Вы выполнили SELECT 'Maria' REGEXP '(ari){0,1}'
Какой результат вы ожидали увидеть?
'Maria' это просто пример из сети. Но если применить только этот синтакс на номер рейса, то не работает:
fln regexp '[a-zA-Z0-9]{1}[a-zA-Z0-9]{1}[a-zA-Z]{0,1}[0-9]{1}[0-9]{0,1}[0-9]{0,1}[0-9]{0,1}[a-zA-Z]{0,1}'
ИЗ задания: xx(a)n(n)(n)(n)(a)
x : (a-zA-Z0-9) --> [a-zA-Z0-9]{1}
x: (a-zA-Z0-9) --> [a-zA-Z0-9]{1}
(a): (a-zA-Z)--> [a-zA-Z]{0,1}
n: (0-9)-->[0-9]{1}
(n):(0-9)-->[0-9]{0,1}
(n):(0-9)-->[0-9]{0,1}
(n):(0-9)-->[0-9]{0,1}
(a): (a-zA-Z)--> [a-zA-Z]{0,1}
Мне нужно что то найти, что б с интексом работало (как индекс в стринге/списке).
^
Match the beginning of a string
$
Match the end of a string.
https://dev.mysql.com/doc/refman/8.0/en/regexp.html#regexp...
я думаю это не поможет. regexp видит мой стринг как салат и говорит есть ли в нем например огурцы или помидоры. Если там еще носки в салате ему все равно. А мне нужно чтоб он полку видел, где слева на право лежит огурец, огурец, помидор и т.д.
'Maria' это просто пример из сети. Но если применить только этот синтакс на номер рейса, то не работает:
fln regexp '[a-zA-Z0-9]{1}[a-zA-Z0-9]{1}[a-zA-Z]{0,1}[0-9]{1}[0-9]{0,1}[0-9]{0,1}[0-9]{0,1}[a-zA-Z]{0,1}'
"Оно не работает" слишком старая шутка. Не смешно.
Что именно "не работает"? Не возвращает 1 для АА0 или не возвращает 0 для 123BBB? Пример данных дайте, с которыми у вас "не работает".
И исправьте выражение как вам выше предложили, сделайте покороче.
А мне нужно чтоб он полку видел, где слева на право лежит огурец, огурец, помидор и т.д.
Try "substring":
эти ^ и $
Я смотрела что ^ и $ делают. Но я не нашла применения. Ок '^ [a-zA-Z0-9]' можно еще проверять.
Но мой стринг если он трехзначный и заканчивается на '[a-zA-Z]%' то надо 0 -->xx(a), а если 8-значный или 7-6-5-4, то надо 1-->xx(a)n(n)(n)(n)(a). Я думаю надо все таки все варианты с if else????
Можно проверить первые две позиции, что на этой субстроке длины два - два метчес для х,
потом третью позицию - если там (а) - отрезать субстроку начиная с 4й позиции до конца, если н - с третьей.
Потом проверить конец (полученной субстроки), и если там (а) - из остатка взять субстроку без последнего элемента, а если н - то оставить как есть.
И в оставшейся в итоге субстроке проверить, что все н, и что длина лежит в [1;4].
Можно проверить первые две позиции, что на этой субстроке длины два - два метчес для х,
потом третью позицию - если там (а) - отрезать субстроку начиная с 4й позиции до конца, если н - с третьей.
Потом проверить конец, и если там (а) - из остатка взять субстроку без последнего элемента, а если н - то оставить как есть.
И в оставшейся субстроке проверить, что все н, и что длина лежит в [1;4].
Спасибо. Я думаю мне понятно и код тоже будет в Вашем варианте покороче, но я уже допишу что начато, то есть: Если стринг длинна 3, то проверь это...Если стринг длинна 4, то проверь то ..и т.д. Мне надо побыстрей и дальше, а Ваш вариант я попробую обязательно, когда время будет.
Еще последняй знак в например в 4х значном стринге SUBSTRING('abcd', -1, 1) или SUBSTRING('abcd', 4, 1) или без разницы?
Я смотрела что ^ и $ делают. Но я не нашла применения.
Плохо. Давайте попробуем собрать мысли в кучу, и может всё-таки показать нам пример с которым "всё не работает"?
в Вашем варианте покороче, но я уже допишу что начато, то есть: Если стринг длинна 3, то проверь это...Если стринг длинна 4, то проверь то ..и т.д. Мне надо побыстрей и дальше
А вам не кажется что с regexp решение всё-таки покороче, и пишется быстрее чем несколько if-esle?
Плохо. Давайте попробуем собрать мысли в кучу, и может всё-таки показать нам пример с которым "всё не работает"?
Проблема в том, что у меня нет определенной концовки номера (если номер больше 3 знаков), чтоб с этим ее тестировать. Плюс ко всему regexp видит мой номер как салат. Только substring + regexp.
у меня нет определенной концовки номера (если номер больше 3 знаков), чтоб с этим ее тестировать
------
Тады - оййй,,, Тады проблем не разрешим от слова вааапще... да-да - даже человекоподобным...
Так что вариант - один - изучить необходимое... ну или выбрать другую специальность...
Да, кстати, а вы вообще понимаете как работает регулярное выражение?
По идее, да. Задание дано явно на знание регулярных выражений. Значит, тема была. Сомневаюсь, что преподаватель на данном этапе хочет выявить студентов, способных хоть частично, рудиментарно реализовать алгоритм для регулярных варажений.
Сомневаюсь, что преподаватель на данном этапе хочет выявить студентов, способных хоть частично, рудиментарно реализовать алгоритм для регулярных варажений.
Я подозреваю, более конкретно это буду на модуле "Алгоритмы" проходить, но это только в 2022. Пока я должна ДБ без теории алгоритмов осилить.
Пока я думаю достаточно знать, что стринг это если я не ошибаюсь список, поэтому на нем индексация в функции субстринг работает.
Что то не так:(((
Я тестирую вариант: xxan(n)(n)(n)a:
select SUBSTRING('11A45BCd', 1, 2) regexp '[a-zA-Z0-9]{2}' and SUBSTRING('11A45BCd', 3, 1) regexp '[a-zA-Z]' and SUBSTRING('11A45BCd', 4, 1) regexp '[0-9]'
and SUBSTRING('11A45BCd', -1) regexp '[a-zA-Z]' and SUBSTRING('11A45BCd', 5) regexp '[0-9]{0,3}';
SUBSTRING('11A45BCd', 1, 2) regexp '[a-zA-Z0-9]{2}'--> тестирую xx
SUBSTRING('11A45BCd', 3, 1) regexp '[a-zA-Z]'--> тестирую a на 3 месте
SUBSTRING('11A45BCd', 4, 1) regexp '[0-9]'--> тестирую n обязательную
SUBSTRING('11A45BCd', 5) regexp '[0-9]{0,3}'-->тест (n), когда n или 0 или 1 или 2 или 3.
Для '11A45BCd' -->1, что не есть правда.
Значит, тема была.
-----
Так в "теме" основное не то что она была, а как ее донесли...
и докопался ли студент после того как "тема была" до понимания вопроса.
Пока что наблюдается что студент просто прошел мимо вопроса...
и даже не имеет чем его подумать...
Способ решения задачи - перебирать наборы значков до получения решения
- не работает в виду большого количества означенных значков...
Пока я должна ДБ без теории алгоритмов осилить.
-----
В твоем вопросе от ДБ - только СЕЛЕКТ. Ну а СЕЛЕКТ в ДБ - 1-2% от того что надо и знать, и понимать...
По РЕГЭКСПу... посмотри сайт где можно его отлаживать - все быстрее пойдет перебор вариантов...
если я не ошибаюсь
-----
Ошибаешься.
Как упрощённо представить себе работу жадного (greedy) регулярного выражения. (на самом деле работают они по-другому, так было бы слишком медленно)
Берём регексп [a-zA-Z0-9]{2}[a-zA-Z]?[0-9]{1,4}[a-zA-Z]? Оно состоит из правил, которым должна соответствовать последовательность символов. Парсер разбирает регексп на правила.
1. 2 буквы или цифры
2. 1 буква или ничего
3. от 1 до 4 цифр
4. 1 буква или ничего
Получаем на вход строчку
ABCD123456
И начинаем проверять. С 1й буквы. ^ буду обозначать на каком месте у нас "курсор" регекспа. Всё что до курсора уже подошло к правилам, всё что после, правилами не проверялось.
^ABCD123456
1. 2 буквы или цифры. AB подходит? Да. Идём дальше.
AB^CD123456
2. 1 буква или ничего. C подходит? Да.
ABC^D123456
3. 1-4 цифры. А у нас D. Не подходит. Откатываемся назад к первому правилу с "вариантами" (где количество символов может меняться)
AB^CD123456
2. 1 буква или ничего. Берём ничего.
AB^CD123456
3. 1-4 цифры. А у нас C. Не подходит. Откатываемся назад до самого начала, больше "ветвящихся" правил у нас не было. Значит наша строка не подошла. Всё, ошибка? Не-а. Отбрасываем первый символ. И начинаем заново.
^BCD123456
1. 2 буквы или цифры. BC подходит? Да. Идём дальше.
BC^D123456
2. 1 буква или ничего. D подходит? Да.
BCD^123456
3. 1-4 цифры. Есть 1234, забираем всё, мы "жадные".
BCD1234^56
4. 1 буква или ничего. 5 как буква не подходит, но как "ничего" вполне.
BCD1234^56
Правила закончились. Значит всё от начала до курсора устроило наше регулярное выражение. Мы "заматчили" BCD1234.
Так понятнее? А теперь, прежде чем говорить что регулярное выражение "не работает", найдите пример, с которым оно работает не так, как вы ожидали.
SUBSTRING(fln, -2, 3) regexp '[0-9]'
Теперь работает. Немного сдесь поменяла.
ELSEIF char_length(fln) > 3 and # hier wird der Fall xxan(n)(n)(n)a getestet.
SUBSTRING(fln, 1, 2) regexp '[a-zA-Z0-9]{2}' and SUBSTRING(fln, 3, 1) regexp '[a-zA-Z]' and SUBSTRING(fln, 4, 1) regexp '[0-9]'
and SUBSTRING(fln, -1) regexp '[a-zA-Z]' and SUBSTRING(fln, -2, 3) regexp '[0-9]' then set result_c = 1;
Теперь работает.
-----
https://www.w3schools.com/sql/func_mysql_substring.asp
Минус две буквы, говоришь? Хи-хи...
И ведь это потом надо будет кому-то учить программировать...
Ты полагаешь что никто до тебя не мог написать нужное по заданию?
Все пытались заставить ТС хоть немного начать думать и дойти до понимания что и как надо делать...
Признаю, что надо было прислушаться раньше и нельзя самой ничего допридумывать ...((( Прочитав это..
^
^
matches the beginning of a string (inside square brackets it can also mean NOT - see below):
SELECT 'Maria' REGEXP '^Ma'; +----------------------+ | 'Maria' REGEXP '^Ma' | +----------------------+ | 1 | +----------------------+
$
$
matches the end of a string:
SELECT 'Maria' REGEXP 'ia$'; +----------------------+ | 'Maria' REGEXP 'ia$' | +----------------------+ | 1 |
+----------------------+.
я придумала, что длинна стринга делится попалам и с '^' проверяеться первая часть, а с '$' вторая(хвост). Еще задавалась вопросом, а что с серединой. Ужос.
Как упрощённо представить себе работу жадного (greedy) регулярного выражения. (на самом деле работают они по-другому, так было бы слишком медленно)
Берём регексп [a-zA-Z0-9]{2}[a-zA-Z]?[0-9]{1,4}[a-zA-Z]? Оно состоит из правил, которым должна соответствовать последовательность символов. Парсер разбирает регексп на правила.
1. 2 буквы или цифры
2. 1 буква или ничего
3. от 1 до 4 цифр
4. 1 буква или ничего
Получаем на вход строчку
ABCD123456
И начинаем проверять. С 1й буквы. ^ буду обозначать на каком месте у нас "курсор" регекспа. Всё что до курсора уже подошло к правилам, всё что после, правилами не проверялось.
^ABCD123456
1. 2 буквы или цифры. AB подходит? Да. Идём дальше.
AB^CD123456
2. 1 буква или ничего. C подходит? Да.
ABC^D123456
3. 1-4 цифры. А у нас D. Не подходит. Откатываемся назад к первому правилу с "вариантами" (где количество символов может меняться)
AB^CD123456
2. 1 буква или ничего. Берём ничего.
AB^CD123456
3. 1-4 цифры. А у нас C. Не подходит. Откатываемся назад до самого начала, больше "ветвящихся" правил у нас не было. Значит наша строка не подошла. Всё, ошибка? Не-а. Отбрасываем первый символ. И начинаем заново.
^BCD123456
1. 2 буквы или цифры. BC подходит? Да. Идём дальше.
BC^D123456
2. 1 буква или ничего. D подходит? Да.
BCD^123456
3. 1-4 цифры. Есть 1234, забираем всё, мы "жадные".
BCD1234^56
4. 1 буква или ничего. 5 как буква не подходит, но как "ничего" вполне.
BCD1234^56
Правила закончились. Значит всё от начала до курсора устроило наше регулярное выражение. Мы "заматчили" BCD1234.
Так понятнее? А теперь, прежде чем говорить что регулярное выражение "не работает", найдите пример, с которым оно работает не так, как вы ожидали.
Спасибо большое. Вам бы вместо нашего Профа надо! Теперь понятно, что можно с этим делать. Очень эффективно работает.
Попытку что-то объяснить
-----
Не всегда требуется объяснять.
Точнее - не очень полезно, с точки зрения развития, давать детальные разъяснения.
Гораздо продуктивнее - подводить к вопросам которые надо изучить и давать возможность это сделать, корректируя только ту часть, где понято неправильно.
В данном случае - чел не понимает практически ничего и подставив решение в задачу останется таким же непонимающим.
Потом ему надо будет как-то делать работу. Непонимая ни с чем работает, ни что делает, ни как может/должно быть...
Ну ответ я написал пока листал 1-ю страницу.
-----
Возьми в голову - не надо писать ответ. Надо писать что надо изучить для...
Что есть, то есть. Но ситуация еще хуже...Теперь правда мне стыдно. Когда все так объяснил...я все равно не правильно что то сделала. Вернее я получаю не то, что ожидаю:
Мое слово: xx(a)n(n)(n)(n)(a)
1. 2 буквы или цифры --> [[a-zA-Z0-9]{2}]
2. 1 буква или ничего-->[a-zA-Z]?
3. 1 цифра --> [0-9]{1}
4.1 цифра или ничего-->[0-9]?
5.1 цифра или ничего-->[0-9]?
6.1 цифра или ничего-->[0-9]?
4. 1 буква или ничего--> [a-zA-Z]?
Вместе: '^[a-zA-Z0-9]{2}[a-zA-Z]?[0-9]{1}[0-9]?[0-9]?[0-9]?[a-zA-Z]?'
Получаем на вход строчку:
'55A5AAAB'
И начинаем проверять. С 1й буквы.
^55A5AAAB
До этого места 55A5^AAABправильно тестирует. С этого нет.(((
[0-9]{1,4} тоже не будет работать. Но тут хоть понятно. Ему достаточно чтоб один из этих знаков был правильный, а остальные ему по хер, если не подходят.
Но когда я ему конкретно с
3. 1 цифра --> [0-9]{1}
4.1 цифра или ничего-->[0-9]?
5.1 цифра или ничего-->[0-9]?
6.1 цифра или ничего-->[0-9]? Почему тоже игнорирует?
Когда в коце еще $ добавила, тогда все правильно! Но почему?
drop function if exists validate_flight_number;
DELIMITER $$
CREATE FUNCTION validate_flight_number (fln varchar(8)) RETURNS int(1)
BEGIN DECLARE result_c int;
IF char_length(fln) >= 3 and fln regexp '^[a-zA-Z0-9]{2}[a-zA-Z]?[0-9]{1}[0-9]?[0-9]?[0-9]?[a-zA-Z]?$' then set result_c = 1;
else set result_c = 0;
END IF;
RETURN result_c;
END$$
DELIMITER ;
Получаем на вход строчку: '55A5AAAB'
И начинаем проверять. С 1й буквы.
^55A5AAAB
До этого места 55A5^AAABправильно тестирует. С этого нет.(((
Продолжение для остатка шаблона [0-9]?[0-9]?[0-9]?[a-zA-Z]?
55A5^AAAB
1 цифра или ничего. А как буква не подходит, но как "ничего" вполне.
55A5^AAAB
1 цифра или ничего. А как буква не подходит, но как "ничего" вполне.
55A5^AAAB
1 цифра или ничего. А как буква не подходит, но как "ничего" вполне.
55A5^AAAB
1 буква или ничего. А как буква подходит.
55A5A^AAB
Правила закончились. Значит всё от начала до курсора устроило наше регулярное выражение. Мы "заматчили" 55A5A.
А вот если бы в конце стояло $, то мы бы имели еще одно правило:
55A5A^AAB
Конец строки. А - это не конец строки. Облом.
"Откаты" я не описáл,
но и так должно быть понятно, что совпадений не будет.
Задание выполнено не правильно, 0 Пунктов((( Буду завтра спрашивать зачем там нужен селект, если функции нужен параметр...но как то так. должно было быть так:
/* c) */
CREATE FUNCTION `validate_flight_number`(fln varchar(8)) RETURNS int
BEGIN
DECLARE fieldresult int;
select fln regexp '^[A-Za-z0-9][A-Za-z0-9][A-Za-z]?[0-9][0-9]?[0-9]?[0-9]?[A-Za-z]?$' into fieldresult;
RETURN fieldresult;
END
Мое:
CREATE FUNCTION validate_flight_number(fln varchar(8)) RETURNS int
BEGIN DECLARE result_c int;
IF char_length(fln) >= 3 and fln regexp '^[a-zA-Z0-9]{2}[a-zA-Z]?[0-9]{1}[0-9]?[0-9]?[0-9]?[a-zA-Z]?$' then set result_c = 1;
else set result_c = 0;
END IF;
RETURN result_c;
END