Перейти к публикации
Поиск в
  • Дополнительно...
Искать результаты, содержащие...
Искать результаты в...
  • Нужна помощь?

    Создайте тему в соответствующем разделе
    Не нужно писать всё в чат!
  • Загляните на торговую площадку

    Там вы можете купить
    всё что касается игровых серверов
  • Не хотите бан?

    Пожалуйста, ознакомьтесь с нашими правилами
    Не нарушайте порядок!
  • Продаёте или покупаете?

    Пользуйтесь услугами гаранта
    Мы сделаем вашу сделку безопасной
NoNameUltima

Фнукция поиска подстроки в строке, с возвратом позиции. Аналог POS из Delphi

Рекомендованные сообщения

 

Функция(файл: Ultima_POS.sqf):

private ["_needle", "_hayStack", "_found", "_cnt", "_i"];
if (_this select 2) then
	{
		_needle		=	toArray(toLower(_this select 0));
		_hayStack	=	toArray(toLower(_this select 1));
	}
else
	{
		_needle		=	toArray(_this select 0);
		_hayStack	=	toArray(_this select 1);
	};
if ( (count _hayStack) < (count _needle) ) exitWith
	{0};
_found	=	0;
_cnt	=	0;
for "_i" from 0 to (count _hayStack)-1 do
	{
		if ( (_hayStack select _i) != (_needle select _cnt) ) then
			{_cnt	=	0;}
		else 
			{
				_cnt	=	_cnt + 1;
				if (_cnt == count _needle) exitWith 
					{_found	=	_i + 1;};
			};
	};
_found

Компиляция:

Ultima_POS	=	compile preProcessFileLineNumbers "Ultima_POS.sqf";

Пример использования:

Private ["_pos"];
_pos    =    ["text", "test find a text in string", false] call Ultima_POS;
if ( _pos > 0 ) then
	{hint format["Подстрока найдена! Начало вхождения: %1", _pos];}
else
	{hint "Подстрока не найдена!";};

*Функция возвращает позицию начала искомой подстроки в строке.

В случае, если подстрока не найдена - вернет 0.

Если подстрока найдена - положительное число(позицию).

Второй (от нуля) параметр False или True  - указывает как искать - с учетом регистра, или без.

Изменено пользователем NoNameUltima (история изменений)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах





А как оно работает с таким вот? 

["teXt", "test fInd a text in String"] call Ultima_POS;

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
2 минуты назад, svalom сказал:

А как оно работает с таким вот? 


["teXt", "test fInd a text in String"] call Ultima_POS;

 

Правильно работает - разный регистр - разный текст.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Тогда необходимо дописать условие в массив, обращать ли внимание на регистр, +иметь возможность проверить сразу несколько слов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А для поиска исключающего зависимость регистра, писать надо правильно -

    [toLower("teXt"), toLower("test fInd a text in String")] call Ultima_POS;

или

    _string    =    toLower('НекАя СтРоКа с ТеКстОм для поиСка');
    _find     =    toLower('ТекСт');
    [_find, _string] call Ultima_POS;

В общем - если надо без учета - преобразовываем в нижний регистр и без учета ищем.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
1 минуту назад, svalom сказал:

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

Для этого существуют циклы - прогоняй да смотри.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Небольшой аналог:

private ["_needle","_haystack","_needleLen","_hay","_found"];
_needle = toLower(_this select 0);
_haystack = toArray (toLower(str(_this select 1)));
_needleLen = count toArray _needle;
_hay = +_haystack;
_hay resize _needleLen;
_found = false;
for "_i" from _needleLen to count _haystack do {
	if (toString _hay == _needle) exitWith {_found = true};
	_hay set [_needleLen, _haystack select _i];
	_hay set [0, "x"];
	_hay = _hay - ["x"]
};
_found
fnc_inString = 	compile preprocessFile "fnc_inString.sqf";

Пример:

_isWeapon = ["gun_",_iClass] call fnc_inString;
if (_isWeapon) then {
	...
};

Тест:

_t1 = diag_tickTime;
for "_i" from 1 to 10000 do {
_lol = ["text", "test find a text in string"] call fn_str1;
};
systemchat str (diag_tickTime - _t1);

// Ultima_POS 12.27 sec
// fnc_inString 8.26 sec

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
7 минут назад, svalom сказал:

// Ultima_POS 12.27 sec // fnc_inString 8.26 sec

У меня другие данные, при более длинных строках.

Можешь провести такой тест:

Private ["_start", "_stop"];

_start	=	diag_tickTime;
for "_i" from 0 to 10000 do
	{
		["1234879659809", "sdjfkdf895811kljj923942934201234569dsjfgldjg9y09y096y0965yh096y0596y09586y09586y09586y09580y9805y1234879659809"] call Ultima_POS;
	};
_stop	=	diag_tickTime;
diag_log format ["TEST ULTIMA: %1",_stop - _start];

_start	=	diag_tickTime;
for "_i" from 0 to 10000 do
	{
		["1234879659809", "sdjfkdf895811kljj923942934201234569dsjfgldjg9y09y096y0965yh096y0596y09586y09586y09586y09580y9805y1234879659809"] call fnc_inString;
	};
_stop	=	diag_tickTime;
diag_log format ["TEST KK: %1",_stop - _start];

Результат:
"TEST ULTIMA: 6.62305"
"TEST BIS: 0.221985"(в А3 есть бисовая функция)
"TEST KK: 8.08899"

Изменено пользователем NoNameUltima (история изменений)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

И до кучи - функция возвращает не только да\нет - но и позицию искомого...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Данный тест нечестен, тк в твоем скрипте строка не преобразовывается в нижний регистр по-умолчанию ))

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
1 минуту назад, svalom сказал:

Данный тест нечестен, тк в твоем скрипте строка не преобразовывается в нижний регистр по-умолчанию ))

_))))))))

так они и в других скриптах не преобразовывается)

да и если преобразовать - ничего не изменится.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Private ["_start", "_stop"];

_start	=	diag_tickTime;
for "_i" from 0 to 10000 do
	{
		[toLower("1234879659809"), toLower("sdjfkdf895811kljj923942934201234569dsjfgldjg9y09y096y0965yh096y0596y09586y09586y09586y09580y9805y1234879659809")] call fn_str2;
	};
_stop	=	diag_tickTime;
systemchat format ["TEST ULTIMA: %1",_stop - _start];
diag_log format ["TEST ULTIMA: %1",_stop - _start];

_start	=	diag_tickTime;
for "_i" from 0 to 10000 do
	{
		["1234879659809", "sdjfkdf895811kljj923942934201234569dsjfgldjg9y09y096y0965yh096y0596y09586y09586y09586y09580y9805y1234879659809"] call fn_str1;
	};
_stop	=	diag_tickTime;
systemchat format ["TEST KK: %1",_stop - _start];
diag_log format ["TEST KK: %1",_stop - _start];

"TEST ULTIMA: 58.875"
"TEST KK: 54.705"
"TEST ULTIMA: 28.397"
"TEST KK: 27.36"
"TEST ULTIMA: 28.595"
"TEST KK: 27.218"

Тестирую прям в игре, а2, время зависит от фпс )

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
1 минуту назад, svalom сказал:

Тестирую прям в игре, а2, время зависит от фпс )

Я в VR тестил, там фпс один и тот же.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Да, в VR твой скрипт чуть чуть быстрее , но не в А2 )

TEST ULTIMA: 3.399
TEST KK: 3.782
TEST ULTIMA: 3.359
TEST KK: 3.798

Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.

Изменено пользователем svalom (история изменений)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

а помимо позиции возврат подстроки, скажем, с этой точки по какую-то конкретную или по конец сообщения, либо наоборот с начала сообщения по эту точку можно как-то сделать?

Было б полезно для функций поиска в тексте каких-то спец символов или слов и выбора части текста из этой строки

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
2 часа назад, svalom сказал:

Да, в VR твой скрипт чуть чуть быстрее , но не в А2 )

Разницы никакой.

Заменил вверху скрипт, - сделал еще чуть быстрее.

Результаты:

11:50:40 "TEST ULTIMA: 5.85303"
11:50:47 "TEST KK: 7.53992"
11:51:09 "TEST ULTIMA: 5.875"
11:51:16 "TEST KK: 7.57104"

 

Почти 2 секунды.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
2 часа назад, 123new сказал:

с этой точки по какую-то конкретную

Это уже не при чем.

Функция на то и функция, что выполняет строгую роль.

А если ты чотко знаешь, что искать надо с Х символа, по Y - ну так вырежи с X по Y да ищи в оставшемся. Тем более, что "отрезать" N элементов массива - проблем то не составляет. - Это уже примитивная работа с массивами, и к поиску отношения не имеет.

Тебе дан инструмент для поиска + как положено возвращающий не просто ДА\НЕТ(нашел, или не нашел), а именно позицию начала вхождения - если таковая имеется, ну и естественно, если позиция положительная => нашел.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Пунктик за размер )

fn_iss={
	private ["_search","_text","_found","_cnt"];
	_search = toArray(toLower(_this select 0));
	_text = toArray(toLower(_this select 1));
	_found = false;
	_cnt = 0;
	for "_i" from 0 to (count _text)-1 do {
		if ((_text select _i) != (_search select _cnt)) then {
			if (_cnt>=1) then {
				_cnt = 0
			};
		} else {
			_cnt = _cnt+1;
			if (_cnt == count _search) exitWith {_found=true;};
		};
	};
	_found
};
_start	=	diag_tickTime;
for "_i" from 0 to 10000 do {
	["1234879659809", "sdjfkdf895811kljj923942934201234569dsjfgldjg9y09y096y0965yh096y0596y09586y09586y09586y09580y9805y1234879659809"] call fn_iss;
};
_stop	=	diag_tickTime;
systemchat format ["TEST: %1",_stop - _start];
systemchat 'end';
// 2.58

 

Изменено пользователем svalom (история изменений)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
20 минут назад, svalom сказал:

 

4.7 она выдает.

именно как есть. даже более упрощенно -

if (_cnt>=1) then { _cnt = 0 };

нет смысла проверять - можно сразу в 0 ставить

 

Но

1. Нет проверки - если искомое > текста(а такое может быть, если не ручками, а где то в скриптах работает).

2. Если текст реально длинный, как и искомое: Будет бежать весь текст до упора - Нет учета что оставшийся текст в какой то момент уже стал меньше искомого.

А так - да. скорее всего лишняя проверка, на совпадение с 1 символом. Толку не дает.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Обновил в первом посте скрипт, - удалил одну лишнюю проверку, т.к. в ней как показала практика нет смысла, и добавил третий параметр - с учетом регистра искать, или без.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас

  • Похожие публикации

    • Автор: BR0wi
      Подскажите где найти людей, которые делаю моды на заказ. К кому вообще обращаться? Или что бы реализовать свои идеи нужно самому "год" сидеть и изучать все механики модинга?
    • Автор: CubeIn
      Приветствую господа, хочу создать новый проект, уникальный, но для этого нужен маппер.
      Я оставлю здесь свой дискрод, напишите в лс, кто готов взяться за крупный проект.
      4me#4542
    • Автор: 123new
      Вижу крайне много любопытных вопросов по поводу идентификаторов игрока в игре. Что же, разжую для не знающих немного.
       
      В игре есть следующие типы идентификаторов:
      1. Steam64ID идентификатор профиля игрока (на пиратках его UID называют), примерно такой: 765475....65 (17 цифр).
      2. Так называемый мною, BIS ID - uid из окна (консоли) сервера игры и ADM-файлов логов сервера, который пишется самой игрой
      3. Battleye GUID игрока.
       
      Первый идентификатор (Steam64ID) на ПК является прямым идентификатором стим-профиля игрока, уникальным у каждого игрока. Т.е. публичным идентификатором вашего профиля для большинства стим-игр (например, Counter-Strike).
      Второй идентификатор (BIS ID) является определенной хеш-суммой, полученной из Steam64ID посредством конвертации сначала в sha256, а затем в base64. Спасибо за это разъяснение и пример кода-конвертации авторам игры на своем официальном форуме.
      Третий идентификатор (Battleye GUID) является публичным идентификатором Battleye античита, получаемый также из Steam64ID поcредством получения его хеш-суммы MD5. Этот же идентификатор есть в логах сервера от Battleye, в любых RCON-приложениях (DART, BEC и т.п.), также его можно конвертировать самим.
       
      Так вот, как же получить Steam64ID:
      1. Зайти на любой ресурс, предназначенный для сбора таких данных. например на: https://steamid.io/
      2. Ввести ссылку на ваш стим-профиль
      3. Получить результат из кучи данных, одно поле из которых и будет содержать ваш Steam64ID
       
      Как получить BIS ID:
      1. Открыть любой Phyton v2.7 -конвертер в интернете, например: https://onecompiler.com/python2/3ycz55xew
      2. Ввести в него следующий код:
      # Hello World program in Python from hashlib import sha256 from base64 import b64encode def construct_bi_uid(steam_id): hashed = sha256() hashed.update(str(steam_id)) return b64encode(hashed.digest()) print construct_bi_uid(76514925976798981) 3. заменить 76514925976798981 на ваш Steam64ID
      4. Отправить код в исполнение, нажав Execute.
      5. Получить результат
       

      Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.
      [Альтернатива] Метод на основе PHP:
      <?php /** * This is how you get user id (bohemia id) like you see in .ADM files from steam id. */ $steam_id = "76514925976798981"; $user_id = base64url_encode(hash('sha256', $steam_id, true)); function base64url_encode($data) { $b64 = base64_encode($data); if ($b64 === false) { return false; } $url = strtr($b64, '+/', '-_'); return $url; } echo $user_id; [Альтернатива] Метод для javascript - node.js:
      var crypto = require('crypto'); var body = "76514925976798981"; var hash = crypto.createHash("sha256"); var hash_result = hash.update(body, 'utf8').digest('base64'); console.log(hash_result);  
      Как получить Battleye GUID:
      1. Открыть любой ресурс с готовой формой конвертирования, например:
      https://armstalker.com/guid/
      https://dayzrussia.com/f/index.php?pages/dayzguid/
      либо написать свою, на основе данных, предложенных на странице Github
      https://gist.github.com/chris579/53053b6d6438df9a9718c23c0d6bbd69
      Оставлю ниже код для Phyton:
      # Thanks to gunlinux import md5 steamid=76514925976798981 temp = "" for i in range(8): temp += chr((steamid & 0xFF)) steamid >>= 8 m = md5.new("BE"+temp) print m.hexdigest() Код для PHP:
      var crypto = require('crypto'); var body = "76514925976798981"; var hash = crypto.createHash("sha256"); var hash_result = hash.update(body, 'utf8').digest('base64'); console.log(hash_result); '2. Вставить в поле ввода UID(Steam64ID) ваш Steam64ID
      3. Нажать кнопку конвертирования или исполнить код, и получить в готовом виде Battleye GUID
       
      Возможно имеются и другие методы и наработки в получении данных идентификаторов более простыми методами, на других языках, либо автоматически. Я описал лишь известные мне.
      Все желающие могут добавить в комментариях свои способы конвертаций, возможно это поможет кому-либо.
    • Автор: 6agu
      Поставил
      Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.
  • Наш выбор

×
×
  • Создать...

Важная информация

Используя этот сайт, вы автоматически обязуетесь соблюдать наши Правила и Политика конфиденциальности.
Чтобы сделать этот веб-сайт лучше, мы разместили cookies на вашем устройстве. Вы можете изменить свои настройки cookies, в противном случае мы будем считать, что вы согласны с этим.