On-line: Andrey, SergKis, гостей 1. Всего: 3 [подробнее..]
АвторСообщение
администратор




Пост N: 1865
Зарегистрирован: 20.02.11
ссылка на сообщение  Отправлено: 15.12.22 14:02. Заголовок: hb_hCaseMatch() в RU2151


не понимаю как заставить хеш массив игнорировать регистр ключа . С латиницей работает отлично, но если ключ в кириллице , то никакие hb_hCaseMatch() не помогают.
Может что еще нужно прописать чтоб нормально игнорировался регистр ?
 
func main()
local aHash := hb_Hash()


REQUEST HB_CODEPAGE_RU1251
hb_cdpSelect( "RU1251" )


hb_hCaseMatch( aHash, .F. )
hb_hSet( aHash, "тест", "тест пройден" )

? "ключ в верхний регистр", if( hb_hHasKey(aHash, "ТЕСТ") , aHash["ТЕСТ"] , "ключ не найден" )
? "ключ в нижний регистр", if( hb_hHasKey(aHash, "тест") , aHash["тест"] , "ключ не найден" )


wait

return nil


результат такой
 
ключ в верхний регистр ключ не найден
ключ в нижний регистр тест пройден
Press any key to continue...
ключ в нижний регистр тест пройден

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 27 , стр: 1 2 All [только новые]


постоянный участник




Пост N: 4182
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 15.12.22 14:47. Заголовок: Игорь, у тебя правил..


Игорь, у тебя правильно реагирует, т.е. ты просишь исп. ключ "тест" в hash, как есть, т.е. hb_hCaseMatch( aHash, .F. ) и
только такой ключ находится, остальные нет, т.е. для др. вариантов переводи ключ в upper (см. THmgData или используй)

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 1866
Зарегистрирован: 20.02.11
ссылка на сообщение  Отправлено: 15.12.22 16:27. Заголовок: SergKis пишет: Игор..


SergKis пишет:

 цитата:
Игорь, у тебя правильно реагирует, т.е. ты просишь исп. ключ "тест" в hash, как есть, т.е. hb_hCaseMatch( aHash, .F. )


я и hb_hCaseMatch( aHash, .T. ) пробовал тот же результат
если ключ латиницей "test" , то находит и aHash['test'] и aHash['TEST'] нормально
если ключ кириллицей "тест" то только строгое соответствие , вне зависимости от hb_hCaseMatch()

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 4183
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 15.12.22 18:47. Заголовок: Haz пишет если ключ ..


Haz пишет
 цитата:
если ключ кириллицей "тест" то только строгое соответствие , вне зависимости от hb_hCaseMatch()


Столкнулся с таким поведением давно, потому сделал в THmgData переменную и танцую с ней
(по возможности, свои ключи в EN, от пользователя ключи с ::lUpp := .T. и метод ниже),
т.е. везде исп. THmgData, а не чистый hash
METHOD Upp( Key ) INLINE iif( HB_ISCHAR( Key ) .AND. ::lUpp, Upper( Key ), Key )

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 1867
Зарегистрирован: 20.02.11
ссылка на сообщение  Отправлено: 15.12.22 19:23. Заголовок: SergKis пишет: Стол..


SergKis пишет:

 цитата:
Столкнулся с таким поведением давно, потому сделал в THmgData


Понятно, значит косяк харбура. Придется прикручивать костыли.
Спасибо Сергей.

Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 686
Зарегистрирован: 08.07.06
ссылка на сообщение  Отправлено: 16.12.22 19:17. Заголовок: Сталкивался с такой-..


Сталкивался с такой-же ситуацией несколько лет назад с таки же эффектом.

Разработчики Harbour ничего внятного не ответили. Региональные кодировки в case match не попадают и это действительно косяк.

FUNC Main() 

LOCAL h := { "abc" => 1, ;
"Def" => 2, ;
"GHI" => 3, ;
"абв" => 4, ;
"Где" => 5, ;
"ЖЗИ" => 6 ;
}

REQUEST HB_LANG_RU
REQUEST HB_CODEPAGE_RU866

hb_CDPSelect("RU866")
hb_LangSelect("RU")

hb_hCaseMatch(h, .F.) // ignore case

? "ABC =", h["ABC"] // 1
? "DEF =", h["DEF"] // 2
? "ghi =", h["ghi"] // 3
? "АБВ =", h["АБВ"] // RTE: BASE/1132 - wrong array arguments
? "ГДЕ =", h["ГДЕ"]
? "жзи =", h["жзи"]

RETURN NIL


Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 4184
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 16.12.22 19:57. Заголовок: Sergy пишет Регионал..


Sergy пишет
 цитата:
Региональные кодировки в case match не попадают и это действительно косяк


Не соглашусь, т.к. все зависит от цели применения.
EN символы отрабатываются case match, языковые ключи как есть работают - понятный вариант.
Если надо сохранить все ключи из базы (как написаны) - это один алгоритм
Если надо группировать ключи (возможны варианты с ключами) - это другой
Если вводите в GET и сразу в hash, то тоже возможны варианты ...
Все на усмотрение программиста, INDEX на текстовые поля базы, как правило, в upper переводят,
можно и через свои ф-ии и т.д.

Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 687
Зарегистрирован: 08.07.06
ссылка на сообщение  Отправлено: 16.12.22 20:09. Заголовок: Примеры с "abc&#..


Примеры с "abc" и "ABC" работают, а "абв" и "АБВ" нет. Что это, если не косяк ?
Если бы было заявлено, что "работает только с кодами ascii 0..127 - никаких вопросов.
Но такого нет в описании, да и по отзывам в гуглоформе - с европейскими кодировками тоже все норм.

Поэтому останусь при своем humble opininon. )) Понадобилось один раз, наступил на грабли, больше так не делаю.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 4185
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 16.12.22 20:20. Заголовок: Sergy пишет Примеры ..


Sergy пишет
 цитата:
Примеры с "abc" и "ABC" работают, а "абв" и "АБВ" нет. Что это, если не косяк ?


Каким алгоритмом делать перевод в upper или lower в не зависящей от языка ф-ии поиска в hash, то что стоит
RU1251 - это частный случай, а если нет языковой таблицы или не установлена а ключи hash используются.
LV866 - такой языковой таблицы нет в windows от слова совсем (три языка), что и как должен работать поиск в hash
не зная алгоритмов upper\lower

 цитата:
Понадобилось один раз, наступил на грабли, больше так не делаю.


Так это изучение предмета.

Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 688
Зарегистрирован: 08.07.06
ссылка на сообщение  Отправлено: 16.12.22 20:33. Заголовок: SergKis пишет: Каки..


SergKis пишет:

 цитата:
Каким алгоритмом делать перевод в upper или lower в не зависящей от языка ф-ии поиска в hash, то что стоит
RU1251 - это частный случай, а если нет языковой таблицы или не установлена а ключи hash используются.
LV866 - такой языковой таблицы нет в windows от слова совсем (три языка), что и как должен работать поиск в hash


Предположу, что точно таки-же, как и UPPER() / LOWER().
Ведь кодовая страница задана и они работают с латиницей и кириллицей одинаково, то должен работать и поиск ключей хэша - тоже одинаково.

Посмотрел тут реализацию хэшей. Мало чего понимаю в Си, но уткнулся в модуле itemapi.c в функцию
hb_itemStrICmp( PHB_ITEM pFirst, PHB_ITEM pSecond, HB_BOOL bForceExact ) - именно она вызывается, если игнорируется CaseMatch.
...
/* Both strings not empty */
if( nMinLen )
{
PHB_CODEPAGE cdp = hb_vmCDP();
if( cdp && ! HB_CDP_ISBINSORT( cdp ) )
iRet = hb_cdpicmp( szFirst, nLenFirst, szSecond, nLenSecond,
cdp, bForceExact );
else
{
...

Запрос кодовой страницы идет. Но так понимаю, что где-то глубоко внутри движка Harbour не установлен
HB_CDP_ISBINSORT() - поэтому "наши" кодовые страницы и глючат... ((

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 4186
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 16.12.22 20:45. Заголовок: Sergy пишет Посмотре..


Sergy пишет
 цитата:
Посмотрел тут реализацию хэшей


Посмотрите реализацию языков, там алгоритмы\таблицы соответствия для upper\lower, т.е. если нет реализации
языка в hb, то нет и upper\lower алгоритмов, как, например, LV866. В версию unicode мы добавляем описание
для LV866 сами, upper\lower работают, только по этой причине. Повторю, работа языкового ключа в hash, работает
в значении как есть, т.е. ключ может быть установлен и найден в независимости от уст. языковой страницы, т.к. не
делает перекодировку в upper\lower с повреждением ключа (от не верного или отсутствующего языка).
Что разумно, по мне

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 4102
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 17.12.22 09:56. Заголовок: Haz пишет: h..


Haz пишет:

 цитата:
hb_hSet( aHash, "тест", "тест пройден" )

? "ключ в верхний регистр", if( hb_hHasKey(aHash, "ТЕСТ") , aHash["ТЕСТ"] , "ключ не найден" )
? "ключ в нижний регистр", if( hb_hHasKey(aHash, "тест") , aHash["тест"] , "ключ не найден" )



если изменить первую строку на

hb_hSet( aHash, "ТЕСТ", "тест пройден" )

то ключ на нижнем регистре находится

Это конечно не решение, но хоть как-то..

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 4103
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 17.12.22 10:27. Заголовок: Посмотрел внимательн..


Посмотрел внимательнее код, и возник вопрос: а является ли харборовский хеш хешем ?
Преобразования строки в хеш-значение не увидел.
В функции hb_hashValuePtr, если значение не найдено, то ключ просто добавляется в хеш без всякого преобразования.
А поиск выполняется методом половинного деления путем простого сравнения строк, если ключи символьные, ну или дат

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 4104
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 17.12.22 12:19. Заголовок: Pasha пишет: если и..


Pasha пишет:

 цитата:
если изменить первую строку на

hb_hSet( aHash, "ТЕСТ", "тест пройден" )

то ключ на нижнем регистре находится

Это конечно не решение, но хоть как-то..



Извиняюсь, ошибся, так тоже не работает

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 1868
Зарегистрирован: 20.02.11
ссылка на сообщение  Отправлено: 19.12.22 11:33. Заголовок: SergKis пишет: в зн..


SergKis пишет:

 цитата:
в значении как есть, т.е. ключ может быть установлен и найден в независимости от уст. языковой страницы


Сергей, потестировал различные кодовые страницы. Только в EN работает игнор регистра ключа. Любые значения "как есть" находит даже если страница не соответствует строке. Это скорее всего говорит о том , что где-то в алгоритмах хеша кодовая страница принудительно установлена на EN.и только в ней корректно работает Upper/Lower.
Легко убедиться если при установленной EN вывести на экран UPPER / LOWER строки к примеру в кодировке 1251, она всегда будет выводиться "как есть". Думаю проблема где то рядом.

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 4105
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 19.12.22 12:39. Заголовок: Haz пишет: Сергей, ..


Haz пишет:

 цитата:
Сергей, потестировал различные кодовые страницы. Только в EN работает игнор регистра ключа. Любые значения "как есть" находит даже если страница не соответствует строке. Это скорее всего говорит о том , что где-то в алгоритмах хеша кодовая страница принудительно установлена на EN.и только в ней корректно работает Upper/Lower.
Легко убедиться если при установленной EN вывести на экран UPPER / LOWER строки к примеру в кодировке 1251, она всегда будет выводиться "как есть". Думаю проблема где то рядом.



Практически у всех, в том числе у русских, кодовых страниц установлен флаг HB_CDP_ACSORT_NONE. Ну а функция hb_itemStrICmp при сравнении строк при такой установке переводит в upper без учета кодовой страницы. Вот и получаем. Увы
И да, харборовский хеш - это никакой не хеш, это просто отсортированный по ключам массив. Я такие отсортированные массивы использую еще с 90-х годов прошлого века, только хешем их не называю. Тоже увы.

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 1869
Зарегистрирован: 20.02.11
ссылка на сообщение  Отправлено: 19.12.22 13:50. Заголовок: Pasha пишет: hb_it..


Pasha пишет:

 цитата:
hb_itemStrICmp при сравнении строк при такой установке переводит в upper без учета кодовой страницы. Вот и получаем. Увы


Паша, спасибо за пояснения двойного "увы". Все стало ясно по использованию хеша. Мне в основном он нужен как переходник Hash <-> json , поиск по ключам в хеше удобнее, чем json строку парсить. Буду иметь ввиду, что если прилетит json с кючом в другом регистре будет ошибка. Придется делать дополнительные проверки через hb_JsonDecode( upper(json), @aHash )

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 4187
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 19.12.22 15:56. Заголовок: Haz пишет Придется д..


Haz пишет
 цитата:
Придется делать дополнительные проверки через hb_JsonDecode( upper(json), @aHash )


В своей версии THmgData\TKeyData имею метод
 
METHOD Json( cJson ) INLINE iif( HB_ISCHAR(cJson), ( cJson := SubStr( cJson, At ("{", cJson) ), ;
cJson := Left( cJson, RAt("}", cJson) ), ;
::aKey := hb_jsonDecode( cJson ), Self ), ;
hb_jsonEncode( ::aKey, .F. ) )
Работаю с ним так
o := oHmgData() // oKeyData()

cj := ... // строка json полученная

o:Json(cj) // можно o:Set(hb_jsonDecode( cj ))

FOR EACH a IN o:GetAll()
ky := upper(a[1]) // ключ приводим к одному значению
// тут подвод dbSeek или dbAppend
REPL R_KY with ky, R_KEY with a[1], R_VAL with a[2] // условная команда
NEXT


Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 1870
Зарегистрирован: 20.02.11
ссылка на сообщение  Отправлено: 20.12.22 11:11. Заголовок: SergKis пишет: В св..


SergKis пишет:

 цитата:
В своей версии THmgData\TKeyData имею метод


Логика понятна и вполне рабочая, ( делал почти так через hbclass() )есть маленькая неприятность с самим json. Вместе с Михаилом поупражнялся со строчками json различных api. Каких там только чудес нет. К примеру , значение ключа это массив , в котором еще массивы и вложенные json строки..
Чтобы найти ксе ключи нужно полностью распарстть всю строку или в рекурсии прогнать весь полученный хеш. Я пошел по пути второму, даже строится дерево хеша или массива , типа визуального просмотра. Из за перегруза пока бросил, но идея осталась следующая {
1 из json получить хеш
2 рекурсия по хешу и получение всех ключей, пути к ним и их значений.
3 тут как раз объектная модель представления хеш,
. это полезно когда большая вложенность ключей и полный адрес значения получается не читаемый.Здесь каждый ключ представлен тремя сущностями - имя, путь и значение.
4 ну и сама обработка объектов.

PS. попутно получил функцию просмотра хеша в стандартном дереве минигуи , с узлами и вложенностью, что в принципе удобно при отладке

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 4188
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 20.12.22 11:33. Заголовок: Haz пишет Каких там ..


Haz пишет
 цитата:
Каких там только чудес нет ...
Чтобы найти ксе ключи нужно полностью распарстть всю строку или в рекурсии прогнать весь полученный хеш.


Полностью согласен с выводами , т.к. надо самому по разному разобрать тексты с json, например, вставкой CRLF разбить на
простые строки-элементы и построчно проводить обработку алгоритмами, определяя, что в строке json, массив или еще какая хрень.
Выше показал ~ вариант только для 1-го пункта из списка, т.к. речь шла о hash и повторных ключах (у нас это не считается ошибкой,
это, скорее, новое значение для ранее прошедшего ключа в разном написании)

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 4189
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 20.12.22 17:08. Заголовок: Haz пишет Чтобы найт..


Haz пишет
 цитата:
Чтобы найти ксе ключи нужно полностью распарстть всю строку или в рекурсии прогнать весь полученный хеш. Я пошел по пути второму, даже строится дерево хеша или массива


Как обрабатываешь такие строки (json 5) ?
j := [{ recid: 1, fname: 'John', lname: 'Doe', email: 'john@gmail.com', profit: 2500, sdate: '1/3/2012' }]
a := hb_jsonDecode(J)
? "получена длинна массива:",len(a)
дает результат:
получена длинна массива: 0

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 1871
Зарегистрирован: 20.02.11
ссылка на сообщение  Отправлено: 20.12.22 21:28. Заголовок: SergKis пишет: json..


SergKis пишет:

 цитата:
json 5)


Ну только разбором строки т.к. hb_jsonDecode() не понимает json 5 и , соответственно, хеш массив не сформирует.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 4190
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 20.12.22 21:52. Заголовок: Haz пишет Ну только ..


Haz пишет
 цитата:
Ну только разбором строки


Это 2-ой случай, когда дают таблицы в json 5, правда не сложные и пока обхожусь вариантом привода к json
 
j := SubS( J, At ("{", j) )
j := Left( J, RAt("}", j) )
j := left(j, 2)+'"'+subs(j, 3)
j := StrTran(j, ":", '":')
j := StrTran(j, ", ", ', "')
j := StrTran(j, "'", '"')
a := hb_jsonDecode(j)
? j
? "получена длинна массива:",len(a)
получаем строку
{ "recid": 1, "fname": "John", "lname": "Doe", "email": "john@gmail.com", "profit": 2500, "sdate": "1/3/2012" }
получена длинна массива: 6

Но если что то сложнее, то придется разбирать.
Думал, что ты сталкивался, потому спросил.

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 1872
Зарегистрирован: 20.02.11
ссылка на сообщение  Отправлено: 20.12.22 22:06. Заголовок: SergKis пишет: Дума..


SergKis пишет:

 цитата:
Думал, что ты сталкивался, потому спросил.

Сергей, так тут вариантов нет, только строку парсить.
Сталкивался, при разборе скачанного HTML .
К сожалению поддержки 5 версии в харбуре нет, все только строковыми операциями и каждый раз индивидуально.

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 1873
Зарегистрирован: 20.02.11
ссылка на сообщение  Отправлено: 21.12.22 09:04. Заголовок: SergKis пишет: Как ..


SergKis пишет:

 цитата:
Как обрабатываешь такие строки (json 5) ?


Сергей, глянь здесь.
Вдруг пригодится.
https://github.com/imsys/JSON-ADVPL/blob/master/lib/JSON.prg

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 4191
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 21.12.22 12:49. Заголовок: Haz пишет глянь здес..


Haz пишет
 цитата:
глянь здесь


Спасибо
Попробовал взять строку json (из примера по ссылке) через hb_jsonDecode() :
{"Products": [{"Name": "Water", "Cost": 1.3}, {"Name": "Bread", "Cost": 4e-1}], "Users": [{"Name": "Arthur", "Comment": "Hello\" \\World"}]}
работает и без ф-ии из ссылки
 
j := hb_memoread(".\_c_.json")
j := StrTran(j, '\"', "")
j := StrTran(j, '\\', "")
a := hb_jsonDecode(j)
? ".\_c_.json", a,"получена длинна массива:",len(a)
for i:=1 to len(a)
? hb_hKeyAt(a,i),"=>",v:=hb_hValueAt(a,i),valtype(v)
? i, v
for each m in v
? hb_valtoexp(m)
next
next
?
результат
Harbour MiniGUI Extended Edition 22.12.1 (32-bit) ANSI
.\_c_.json HASH[2] получена длинна массива: 2
Products => ARRAY[2] A
1 ARRAY[2]
{"Name"=>"Water", "Cost"=>1.3}
{"Name"=>"Bread", "Cost"=>0.4}
Users => ARRAY[1] A
2 ARRAY[1]
{"Name"=>"Arthur", "Comment"=>"Hello World"}


Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 1874
Зарегистрирован: 20.02.11
ссылка на сообщение  Отправлено: 21.12.22 23:18. Заголовок: SergKis пишет: Попр..


SergKis пишет:

 цитата:
Попробовал взять строку json (из примера по ссылке)

ну так там , в отличии от твоей строки есть ключ массива и все ключи в массиве с кавычками. Можно приводить строку к "стандартному" виду, а можно функцию аналог hb_jsondecode() под себя подправить. Все зависит от того как часто и что приходится делать.
Как показал мой опыт, этот путь бесконечен. Только вроде все сделал, и тут json с левой резьбой...

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 4192
Зарегистрирован: 17.02.12
ссылка на сообщение  Отправлено: 21.12.22 23:47. Заголовок: Haz пишет Только вро..


Haz пишет
 цитата:
Только вроде все сделал, и тут json с левой резьбой...


На эту тему были мысли использовать php (к LetoDbf прикручивается) или js, но пока необходимости не было,
json 5 -> json просто переводился.

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 27 , стр: 1 2 All [только новые]
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 337
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет