Страницы: 1 2 След.
RSS
Странное поведение Like (VBA)
 
Мое почтение, джентльмены.
Есть интерес послушать специалистов, почему Like в варианте 3 выдает True, а в последнем варианте ошибку?

Код
Sub TestLikeERR()

    Debug.Print "-" Like "[1-4-6]" 'True
    Debug.Print "5" Like "[1-4-6]" 'False
    Debug.Print "5" Like "*[1-4-6]" 'почему True?
    
    Debug.Print "F" Like "[F-F]" 'True
    Debug.Print "F" Like "*[F-F]" 'почему Error?

End Sub


Настолько впечатлен этим инструментом, что разместил вопрос и здесь.
Изменено: bedvit - 14.05.2025 22:49:33
«Бритва Оккама» или «Принцип Калашникова»?
 
Добрый день, Виталий!
Не понятна цель вопроса об особенностях реализации в MS исходного кода оператора Like, которого никто здесь не видел и не увидит. Разве что, интересны наши фантазии на этот счет  :)
Есть правила составления шаблонов для оператора Like, по ним нужно и писать код.
При несоблюдении этих правил VBA имеет право поступить так, как сработает внутренний код, вернув то, что получится: True/False/Error
В шаблоне "[1-4-6]"  повторный символ "-" не на месте, т.к. это не символ диапазона (синтаксис нарушен) и он ни в начале списка, ни в конце, где ему положено быть по правилам.
VBA при этом на ошибку не наткнулся, а посчитал шаблон "[1-4-6]" как:
символ в диапазоне "[1-4]"  ИЛИ символ "-"  ИЛИ символ "6"
И в простом шаблоне "[F-F]" VBA, так и быть, посчитал некорректно заданный диапазон отсортированным по возрастанию.
Но в более сложном fuzzy-шаблоне "*[F-F]" тот же диапазон "[F-F]", чтобы не создавать неопределенности, мог посчитатьcя некорректным, например, возможно отсортированным по убыванию, это означает ошибку. Или код в таком случае мог использовать "жадный" поиск и тупо откусить первый символ в шаблоне (поэтому и True  в строке 3), или вообще что угодно.

Пофантазировал, и что теперь?  ;)  
Изменено: ZVI - 15.05.2025 09:27:44
 
ZVI, Владимир, приветствую!
Цель вопроса? наверное пообщаться, выйти покурить в перерыв между работой (я не курю, но здесь-то можно в курилке?)
Цитата
ZVI написал:
символ в диапазоне "[1-4]" ИЛИ символ "-" ИЛИ символ "6"
Да все верно, это валидный паттерн для старщего брата - Регулярных выражений. Можно проверить на https://regex101.com/
Собственно складывается впечатление, что Like писали спустя рукава, начали видимо хорошо, паттерны 1-2,3 выполняются с таким же итогом как и итог регулярных выражений...
Потом что-то пошло не так (что-то не смогли?) или решили, а и так хватит... давайте сделаем ограничение на это ("-" разделитель только в конце или в начале, что в регулярках не обязательно), да и норм...
Сомнительно... но Окей...
Смотрим далее
Код
    Debug.Print "F" Like "[" 'Error
    Debug.Print "" Like "[" 'почему False?

Первый паттерн явно ошибочен, не закрыта скобка. Все понятно - ошибка. А второй возвращает False, т.е. маска норм, вопросов не вызывает?
Смотрим регулярки - во всех двух случая ошибочная маска - ошибка (там же на сайте regex101 можно проверить, для всех языков)

Хорошо, специалисты говорят, не надо смотреть ругулярки, смотри спецификацию к оператору Like и не выдумывай лишнего...
Если петтерн не соответствуеn спеке - это все UB...

Ну Ок говорю я, а где в спеке написано что задать диапазон следующим образом [F-F] ошибка? И почему если это ошибка, не выходит сообщение в VBA?
Я вижу в спеке лишь ошибку, если первое значение больше второго (должно быть в возрастающем порядке)
..."[A-Z] является допустимым шаблоном, но [Z-A] не является."...
Если ошибка, зачем возвращается True (я понимаю еще False вместо ошибки, но тоже так себе)? Т.е. все валидно и даже положительный результат сравнения!

Что в итоге: абы как составленный инструмент, где -то возвращающий False, вместо ошибки, где-то True!!!, где-то считает в одном контексте, где то в другом при одинаковой маске или одинаковых строках.
Изменено: bedvit - 15.05.2025 10:02:05
«Бритва Оккама» или «Принцип Калашникова»?
 
вроде у ZVI исчерпывающее и очень логичное разъяснение. Со "сносками", допущениями, оговорками.
bedvit, непонятно, что осталось непонятным )
 
nilske, осталось... читаю спецификацию:
"Дефис ( - ) может стоять либо в начале (после восклицательного знака, если он используется), либо в конце charlist , чтобы соответствовать самому себе. В любом другом месте дефис используется для обозначения диапазона символов."
Пишу код:
Код
Debug.Print "-" Like "[1-2-3]" 'почему True

Вопрос: почему True?
«Бритва Оккама» или «Принцип Калашникова»?
 
bedvit, встречный вопрос - почему такой шаблон, что он обозначает, какова его цель, можно ли было достичь этой цели более правильным шаблоном?
 
nilske, встречный вопрос: а что неправильного в моем шаблоне, какой части спецификации он не соответствует?
«Бритва Оккама» или «Принцип Калашникова»?
 
bedvit, ваш вопрос был вполне понятный и очень однозначный
Цитата
bedvit написал:
почему True?
выше ZVI на него ответил вполне однозначно, вы хотите получать на него ответ ещё несколько раз?
поэтому я предложил Вам лучше обсудить ту цель, которую пытаетесь достичь данным шаблоном.
Эта цель для Вас не может быть не ясна, не понимаю почему Вы не хотите дополнить тему своими целями. О них также были вопросы выше.
Если целью является доказать, что Like работает "неправильно" или найти то, о чём не указано к документации по нему, то ведь цель достигнута, что ещё обсуждать?
 
nilske, Вы считаете, что Like работает неправильно? И считаете, что это обсуждать не нужно? Т.е. работет неправильно, ну и ладно, че обсуждать-то, верно? Правильно ли я вас понял?
«Бритва Оккама» или «Принцип Калашникова»?
 
если появились новые вопросы, то нужно ведь их и обсуждать, разве нет?
давайте обсудим ваш новый вопрос
"Почему Like работает направильно?"
Поэтому что раньше Вы этот вопрос в этой теме не обозначали, а несколько раз спрашивали "Почему True?", даже не указывая, почему должно быть по-другому.
Напишите, как должен правильно работать Like, на ваш вгляд, и почему Вы так считаете?
 
nilske, если прочитать мое сообщение 5, то там есть выдержка из спецификации, где написано, почему должно вернутся False (потому что "-" не в начале и не в конце charlist). А возращается True. Поэтому я и спрашиваю, почему так? Где проблема?
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
ZVI написал:
Не понятна цель вопроса об особенностях реализации в MS исходного кода оператора Like, которого никто здесь не видел и не увидит. Разве что, интересны наши фантазии на этот счет
 
Цитата
написал:
наверное пообщаться,
Поговорить - да, это нормально и приятно.
Вообще, к Like претензии вижу впервые.
Работает в соответствии с описанием и очень быстро.
А все вольности этого оператора при некорректно заданных шаблонах ему прощаю – неизвестно какими мы сами будем в пограничном состоянии  :D  
 
Цитата
написал:
смотри спецификацию
Цитата
написал:
читаю спецификацию
Цитата
написал:
какой части спецификации он не соответствует
Цитата
написал:
выдержка из спецификации

Очень много спецификации bedvit, или Деми Мурыч...?
 
Цитата
bedvit написал:
почему должно вернутся False (потому что "-" не в начале и не в конце charlist)
почему же не в начале и не в конце? Он как раз либо в начале, либо в конце :)
Шаблон "[1-2-3]". Разбирается скорее всего по частям. Первая часть - диапазон от 1 до 2: "[1-2]". Вторая часть - дефис и число 3, которые считываются уже по отдельности, т.к. цифра "2" уже занята диапазоном "1-2": "[-3]". Следуя этой логике - дефис-таки в начале. Но если вдруг, Like начинает разбор шаблона справа налево - то будет обратная ситуация, которую, полагаю, сами достроите("2-3" и "1" и "-").
Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы...
 
Цитата
Дмитрий(The_Prist) Щербаков написал:
Но если вдруг, Like начинает разбор шаблона справа налево
Дмитрий приветствую!
Как хочет, так и сравнивает...и с начала и с конца...пример:
Код
    Debug.Print "5" Like "*[1-4-6]" 'True - диапазон с конца маски
    Debug.Print "2" Like "[1-4-6]"  'True - диапазон с начала маски


Поясню почему возникла эта тема. В С++ нет такого оператора. Я решил максимально точно воспроизвести Like VBA, но у меня не получилось воссоздать этот гениальный алгоритм, где нет четкой парадигмы. Где-то возвращает False, вместо ошибки, где-то True!!! (см. пост 1), где-то считает в одном контексте, где-то в другом, при одинаковой маске или одинаковых строках разные результаты... Где-то маска с открытой скобкой - ошибка "[...", где-то не ошибка (см. сообщение 3) и т.д.

Плюнул, сделал свою реализацию, где [1-4-6] считается валидной маской, всегда считается слева направо, как в регулярках, а не как в Like VBA (в одних случаях с конца, в других с начала, поди угадай какой должен быть результат - см. выше в этом сообщении) . И маска всегда проверяется на закрытую скобку и корректность диапазона "[a-b]" (первый символ не может быть больше последнего, но может быть равен - как в регулярках, в LIke может быть равен, а может быть и ошибка, см. пост 1). т.е. алгоритм должен предполагать только единственный точный валидный! результат, без экстрасенсов и гадалок или возвращать ошибку!
Изменено: bedvit - 15.05.2025 22:59:49
«Бритва Оккама» или «Принцип Калашникова»?
 
Джентльмены, не на то время тратите!

Цитата
написал:
Debug.Print "" Like "[" 'почему False?
Потому что сперва проверяется строка, если пусто, тогла FAlse!

Цитата
написал:
Debug.Print "-" Like "[1-4-6]" 'True
Потому что [1-4-6] = {1-4, "-", 6} = "-"

Цитата
написал:
Debug.Print "5" Like "[1-4-6]" 'False
Потому что [1-4-6] = {1-4, "-", 6} <> 5

Цитата
написал:
Debug.Print "5" Like "*[1-4-6]" 'почему True?
Потому что *[1-4-6] = {1-6} = 5

Цитата
написал:
Debug.Print "F" Like "[F-F]" 'True
Потому что [F-F]= {F} = F

Цитата
написал:
Debug.Print "F" Like "*[F-F]" 'почему Error?
Потому что *[F-F]  это не диапазон!


Звёздочка определяет поведение и преобразует всё в единый диапазон на основании таблицы ASCII, Иззи!
Ошибка, если один символ в диапазоне или шаблон в обратном направлении [F-A] The End!

Тема под снос или закрыта!

В банальных вещах плаваете, господа!
Изменено: Бог Excel и гамбургеров - 16.05.2025 04:30:54
 
Цитата
написал:
... не на то время тратите!
Приветствую!
Та мы в курилке на что хотим, на что и тратим, и никто нам не указ  :D
Почем гамбургеры для народа?  ;)  
Изменено: ZVI - 16.05.2025 14:11:36
 
5500 за один
Изменено: Бог Excel и гамбургеров - 16.05.2025 10:53:29
 
Бог Excel и гамбургеров,  Вы это, поосторожнее с гамбургерами, а то уже бред не относящийся к теме пошел.
По вопросам из тем форума, личку не читаю.
 
БМВ, я просто ответил на вопрос!
 
Цитата
Бог Excel и гамбургеров написал:
я просто ответил на вопрос!
до исправлений был очень странный ответ.
По вопросам из тем форума, личку не читаю.
 
Цитата
Бог Excel и гамбургеров написал:
Потому что сперва проверяется строка, если пусто, тогла FAlse!
А здесь строка пустая, но почему True... ай-я-яй
Код
Debug.Print "" Like "[]" 'True


Цитата
Бог Excel и гамбургеров написал:
Потому что *[1-4-6] = {1-6} = 5
{1-6} = 2 , но почему False... ай-я-яй
Код
Debug.Print "2" Like "*[1-4-6]" 'False


Цитата
Бог Excel и гамбургеров написал:
Потому что *[F-F] это не диапазон!
Извините, а что же это?

Цитата
Бог Excel и гамбургеров написал:
Звёздочка определяет поведение и преобразует всё в единый диапазон на основании таблицы ASCII, Иззи!
Можно ссылку, подтверждающие ваши слова, ибо все это выглядит как, прямо скажем... ваши фантазии. Или троллинг.
Изменено: bedvit - 16.05.2025 14:31:01
«Бритва Оккама» или «Принцип Калашникова»?
 
Цитата
Бог Excel и гамбургеров написал:
Да, конечно. Тут всё подробно:  Microsoft Specification
Не ожидал, что у вас настолько глубокие знания!
Предлагаю бан для этого субъекта, пусть почитает правила форума.
«Бритва Оккама» или «Принцип Калашникова»?
 
можно ссылку, подтверждающие ваши слова о запрете ссылок?
Цитата
написал:
почитает правила форума.
Упс.. А нету ничего! Ещё и с правилами форума не знакомы... Ну как так то? + Мы же в курилке  
Изменено: Бог Excel и гамбургеров - 16.05.2025 19:32:56
 
Предлагаю бан для этого субъекта, пусть почитает правила форума!  
 
Бог Excel и гамбургеров,  понижен до банного короля..
По вопросам из тем форума, личку не читаю.
 
Здравствуйте, коллеги!
Здесь дана более подробная (?) спецификация оператора Like.
Изменено: sokol92 - 17.05.2025 15:52:13
Владимир
 
sokol92, Владимир, спасибо за доп. информацию.
Остались нераскрыты несколько пунктов по ссылке:
1. "If either <expression> or <like-pattern-expression> is Null, the result is Null."
Видим что не всегда выполняется, пример:
Код
Debug.Print "" Like "[]" 'True. По ссылке: <expression> is Null, значит результат Null, т.е. False

2."<like-pattern-charlist-range>: This adds a range of characters to the character list, including all characters considered greater than or equal to the first <like-pattern-charlist-char> and considered less than or equal to the second <like-pattern-charlist-char>. If the end character of this range is considered less than the start character, runtime error 93 (Invalid pattern string) is raised."
Видим что условие выполняется в примере ниже, последний символ НЕ больше первого, но выдается ошибка, пример:
Код
Debug.Print "F" Like "*[F-F]" 'почему Error? ведь True

3.Ничего не поясняется про такой пример:
Код
Debug.Print "5" Like "*[1-4-6]" 'True - диапазон с конца маски?
Debug.Print "2" Like "[1-4-6]"  'True - диапазон с начала маски?
Debug.Print "-" Like "[1-2-3]" 'почему True? ведь "-" не в начале и не в конце.

4."The next characters in <like-pattern-expression> do not form a valid, complete <like-pattern-element> according to the grammar. In this case, runtime error 93 (Invalid pattern string) is raised. Note that this runtime error is only raised if no other result has been produced before pattern matching proceeds far enough to encounter this error in the pattern."
Код
Debug.Print "F" Like "F[" 'почему False, а не Error?

Это стало понятно из тестов, что маска проверяется не всегда до конца, что приводит пользователя в замешательство, когда одна часть результатов False, другая Error 93. Лично вижу, что проверка маски до конца более правильный вариант, в ущерб снижения скорости выполнения для проверки оставшийся части маски. Здесь вопрос к обсуждению, что предпочтительнее: скорость или гарантированная ошибка при некорректной маске?
Опрос: Что для вас важнее?
Изменено: bedvit - 21.05.2025 12:59:46
«Бритва Оккама» или «Принцип Калашникова»?
 
TestAccount, Ну вот ещё один пользователь, думающий что владеет программированием, считающий, что знает больше всех и поэтому общающийся в поучающей манере, позволяя себе раздражительно кричать в чате, типа "запомни" или "просто запомни", высказывать свои оценочные мнения, которые мало кому интересны. Что ж Вы такие агрессивные
Изменено: Msi2102 - 23.05.2025 13:28:04
Страницы: 1 2 След.
Читают тему
Наверх