if not (Key in ['а'..'я', 'a'..'z', #32, #8])

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Ответить
mkazakov
новенький
Сообщения: 52
Зарегистрирован: 24.02.2012 14:04:14
Откуда: Балаково

if not (Key in ['а'..'я', 'a'..'z', #32, #8])

Сообщение mkazakov »

Код: Выделить всё

procedure TForm2.fullnameKeyPress(Sender: TObject; var Key: char);
begin

  if not (Key in ['а'..'я', 'a'..'z', #32, #8]) then
    Key := #0

end;


Пишу простую функцию и тут проблема я так понимаю с кириллицей :shock:

Решал ли кто такой вопрос?
Аватара пользователя
WAYFARER
энтузиаст
Сообщения: 567
Зарегистрирован: 09.10.2009 00:00:04
Откуда: г. Курган

Сообщение WAYFARER »

Используйте onUTF8KeyPress вместо onKeyPress
mkazakov
новенький
Сообщения: 52
Зарегистрирован: 24.02.2012 14:04:14
Откуда: Балаково

Сообщение mkazakov »

Ошибка таже

procedure TForm2.fullnameUTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
begin

if not(UTF8ToSys(UTF8Key)[1] in ['а'..'я', '0'..'9', #8]) then
UTF8Key:=#0;

end;
iskander
энтузиаст
Сообщения: 630
Зарегистрирован: 08.01.2012 18:43:34

Сообщение iskander »

Код: Выделить всё

  if not(UTF8ToSys(UTF8Key)[1] in [#224..#255, #97..#122, #8]) then
    UTF8Key:=#0 ;

Так пойдёт?(только для Windows)
SSerge
энтузиаст
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Сообщение SSerge »

mkazakov писал(а):Пишу простую функцию и тут проблема я так понимаю с кириллицей :shock:

Решал ли кто такой вопрос?


В кодировке UTF8 на текущей реализации lazarus нет понятия "символ". Есть лексическая строковая единица, символом не являющаяся. Кроме того, по большему счету, вы не вправе предполагать какое либо универсальное упорядоченное расположение этих лексических единиц "по алфавиту".

Забывайте о символах (char) и методике Key in []. Что было верно когда-то, уже не так верно. :)

опять же позволю себе цитировать сей гнусный текст: "для вас больше не должно существовать переменных и констант типа char и нет никакой возможности выбрать символ по индексу в строке как в массиве символов. И вы не имеете права применять никакие функции для типов String/AnsiString с указанием позиции символа в строке, задаваемого вами «вручную», если хотите корректных результатов." - http://sirserge.altai.info/articles/?id=41
Аватара пользователя
stikriz
энтузиаст
Сообщения: 612
Зарегистрирован: 15.03.2006 08:37:47

Сообщение stikriz »

SSerge писал(а):и нет никакой возможности выбрать символ по индексу в строке как в массиве символов.


Всё работает нормально, если перевести на WideChar, WideString.

Добавлено спустя 7 минут 4 секунды:
in не работает потому, что значение в множестве должно быть байт, а символ теперь не всегда байт.
SSerge
энтузиаст
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Сообщение SSerge »

stikriz писал(а):сё работает нормально, если перевести на WideChar, WideString.


Для полноты картины, стоило бы обозначить, что "перевести" на WideChar, это значит:

Код: Выделить всё

var 
  w: widestring;
begin
  w:=UTF8ToUTF16('Über'); // correct
  Button1.Caption:=UTF16ToUTF8(w);
end;


а не просто присвоить значение в UTF соответствующей wide, переменной, что в отличие от всяких там дельфей, не работает. Ж)

Ну и пря всяком переводе вы имеете шанс потерять информацию или исказить её. Что в случае с wide в некоторых случаях будет чертовски трудно отследить. И всё ради того чтобы обращаться к элементу строки через скобки? :D Здесь скорее стоит определиться, с какими информационными массивами работаем, чтобы работать с ними без преобразования информации... Уж лезть в wide если всё представлено в utf8 - на это должны быть веские причины.
Аватара пользователя
Brainenjii
энтузиаст
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Сообщение Brainenjii »

С незначительной потерей производителности можно заменить if not (Key in ['а'..'я', 'a'..'z', #32, #8]) на If Not(IsPresent(Key, ['а'..'я', 'a'..'z', #32, #8]))

Код: Выделить всё

 
Function IsPresent(Const aString: String; Const aArray: Array of String): Boolean;
Var
  i: Integer;
Begin
  Result := FALSE;
  For i := Low(aArray) To High(aArray) Do
    If aArray[i] = aString Then
      Exit(TRUE);
End;
SSerge
энтузиаст
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Сообщение SSerge »

Brainenjii

А что, у нас для строк по синтаксису теперь разрешено задание элементов массива диапазонным интервалом?

Код: Выделить всё

Гораздо проще и быстрее по сути 

function IsPresent(symbol:string):boolean;
begin
  Result:=UTF8Pos(symbol,'абвгдекжзийклмноп')>0;
end;
Аватара пользователя
stikriz
энтузиаст
Сообщения: 612
Зарегистрирован: 15.03.2006 08:37:47

Сообщение stikriz »

SSerge писал(а):И всё ради того чтобы обращаться к элементу строки через скобки? :D

Например, для парсеров - там, где надо обработать текст посимвольно.
mkazakov
новенький
Сообщения: 52
Зарегистрирован: 24.02.2012 14:04:14
Откуда: Балаково

Сообщение mkazakov »

еще тема.

Хочу что бы каждое новое слово было с большой буквы

Код: Выделить всё

procedure TForm1.Edit1UTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
begin
      with Sender as TEdit do
    if (SelStart = 0) or
      (Text[SelStart] = ' ') then
          if (UTF8ToSys(UTF8Key)[1] in [#224..#255, #97..#122]) then
             UTF8Key:=UTF8UpperCase(UTF8Key);
end;


Но кириллица работет почему-то через раз :evil:
Ответить