1с проверить строку на латиницу
Дано: много строк (>10000), длина каждой < 40 символов, могут содержать любые алфавитно-цифровые символы, точки и запятые.
Задача: нужно максимально быстро определить, является ли эта строка числом. При этом строка, являющаяся числом, может содержать нули в старших разрядах и нули на хвосте дробной части. Разделителем разрядов может быть как точка, так и запятая. Знака изначально в строке быть не может, поэтому на + и - пофиг.
Например числа:
0100,99900
100
100.99
Не числа:
100.0,12
Asd100xЩ
100.0Ю
Предложите быстрый алгоритм, плз?
умножить на любое число, например 1. если ругнётся - не число.
Попытка, Исключение
(1) Не. Стр*1 - Операция умножения не определена для строковых величин, 1*Стр - умножит всегда, преобразовав по правилам Число()
Если б не нули в начале и конце, прокатило бы:
.
с предварительной заменой запятой на точку. А с нулями - хз.
Очень не хочется посимвольно разбирать строку, ибо много их.
(6) п. 1 - я сходу вижу только посимвольным разбором. Чего как-раз и не хочется. Как быстро нули посчитать?
(7) Игра ума. Лучше алгоритм предложи. Быстрый.
(8) Потому что Число("123") - это число. А число не равно строке. Засунь в конфигуратор - увидишь.
(10) Это написано в (3). Для строки "0100" условие не выполняется. Я ж говорю - проблема в нулях.
(12)не взлетит
(11) без посимвольного не обойтись, на этапе отсечения нулей - перебор будет короче всего
(12) Повезло тебе, что не на китайском пишешь. У них там, грят, около 5000 основных иероглифов. У какая длинная строка с Найти() была бы ;)
если (3) катит с предварительной заменой точек и запятых.
то замени в исходной строке Стр все "0" на любую другую цифирь
(0) а в принципе, как такая задача родилась?
Тест что ли какой-то?
(18) скорее всего автор хочет привести все Наименования какого-то Справочника к числовому виду
(19)Скорее, коды. Когда нарушают уникальность, потом начинают вводить всякую чепуху.
(20) м.б. автор хочет производить какие-то матоперации с наименованиями.
м.б. это лотерейные билеты или номера скидочных карточек покупателя.
(21) коды я отмёл сразу - (22) прав. самое бОлшее я видел 15 знаков кода.
(22) хотя да.
(23) жизни вы не видели, я видела 100:) Они туда закодировали производителя, иерархию и пр.
(24) Боже!
а зачем же так код мучать? реквизит в Справочник нельзя добавить?
(23) На мой взгляд, для решения этой задачи, надо знать полностью условие, потому как от условий возможна разная реализация, сама по себе задача решаема в лоб без всяких проблем, если она единовременная, то можно плюнуть на быстродействие. Допустим, если автор действительно хочет "перекодировать" справочник, то нужен дополнительный алгоритм, потому как при использовании одного алгоритма преобразования строки состоящей из одних цифр или из цифр и каких-то символов в число, может "задвоится" число, т.е. при одинаковом преобразовании строки цифр и строки символов имеем вероятность получить на выходе одно и то же число.
(28) логично. об уникальности я не подумал.
0099.9, 099.9, 99.990 дадут одно число 99.9
Если нужно просто "достать число" - то есть очень простой способ извлечения числа из строки, без перебора.
ре.test(вСтрока)
В точности не уверен, можно потестировать если надо.
(42) Я понял, что нужно еще определить само значение если строка является числом.
(45) :-)
0 будет только если проверяемое выражение начинается не с цифры. А все первые цифры буду превращаться в число, остальное отбрасываться.
(53) Ограничение знаков после запятой. Для 1С это не число
В терминах поставленной задачи эта строка - число, со значением в 1С, равным нулю.
"1.00000000000000000001" - числом.
Потому как все попытки сравнивать строки до и после преобразования функцией "Число", натыкаются на ограниченность разрядов.
(57) можно и не определяться, по такому принципоу пойти
Число("1"+".000000000000000000001"+"1")*10000000000000000000000
(58) не фигня, так многое можно определить и не только строка или число
(59)
Число("1"+"9876543210"+"1")*1000000000000000000000000000000000000000 =
198765432101000000000000000000000000000000000000000
(58)(59) а это - Число("1толиДатолиНет"+".000000000000000000001"+"1")*10000000000000000000000 число ?
(61) Не, ну понятно. Я сказал что принцып такой. Позицию разделителя дробной найти.
(53) Как я понял, 1С не видит больше 20 знаков после точки.
Тогда можно извернуться так.
Часть вторая.усовершенствованная :-):
--------------------
Ну, ладно, это я уже стебаюсь.
Имхо можно эти способы объединить или выбрать более удобный для (0).
КодСимв(<?>)
Синтаксис:
КодСимв(<Символ>)
Назначение:
Возвращает код первого символа, содержащегося в строке.
Параметры:
<Символ> - строковое выражение.
(67)
То и вернет, что строка является числом, и его значение.
Фишка в том, что число в 1С ограниченно 69 разрядами (чего хватает для этой задачи), но при преобразовании его в строку обрезает до 23 знаков после запятой.
(66)
Неправильно отработает, если будет две точки, и они попадут в разные части.
Либо в середине строки будут пробелы, которые попадут в первую часть в конец, во вторую часть в начало.
(71) Легко решается несколькими строками в начале процедуры Сформировать
:-)
не всеже объясните тупым и алкоголикам чем шаблон плох ? медленно ?
(75) Только еще одно уловие поставить надо, если нет дробной части. Просто хотелось не перебором.
(74) Ну чего ты этими шаблонами добьешься? Попробуй че нить подсунуть. К примеру 00А00.5115.1
(76) Не надо доп. условий, там в комментарии пояснено, почему не надо. И перебора там нет - СтрЗаменить-то без перебора работает.
(78) Спортивно средствами встроенного языка.
такое чувство, что из предложенных вриантов не все тестировали (больше писали на угад) + кто скажет что быстрее ? :)
П.С. сам пока думаю. :)
Мда. Не ожидал я такого спортивного интереса, когда тему поднимал :)
Сразу повторю свой ответ на вопрос "а на хрена?" - это действительно игра ума :) Была реальная, но разовая задача, сделал ее "в лоб" перебором, потом стало интересно, а как быстрее, поставил граничные условия, запостил сюда, пошел домой спать :)
Самый быстрый вариант, как ни странно, оказался самым первым, у 2Green. Но он не работает с числами >20 знаков. Результат меня сильно удивил, потому как я думал о первом варианте Рэйва.
Замер производительности показал:
(В тиках - 110 и 117 соответственно)
Дальше идет вариант с регулярными выражениями (154 тика), вариант orefkov'а (187 тиков), вариант Пуделя (551 тик). Остальные варианты пока не померил.
(84) с регулярами заметь, можно весь тект за один присест, не построчно, "рассортировать".
(84) Блин, ты просто моё время с временем Сообщить замерял :))). Я только что проверил - у меня быстрее орефкова (моё 0.004647, орефкова 0.004695)
(84) Попробуй вариант для регулярных не по одной строке, а по "тексту" т.е. строке разделенной "РазделительСтрок". Если конечно в условия задачи вползает.
Да с Шаблон медленно когда не число зато код простой, можна и еще просче :)
.
(88) Не-а. Правда твой код я переписал, оставил только идею:
(87) Надо "тестовый стенд" для этого переписывать. Сейчас он выглядит так:
1. Исходные данные живут в дбф. 10000 строк. Строки формировались так:
1.1. Случайная длина строки от 1 до 40
1.2. Каждый символ строки генерировался случайным образом из набора "01234567890.,AB". Такой набор получил опытным путем - меня устроил процент "правильных" чисел:
15% (точнее - 1360 из 10000)
1.3. Массив строк хранится в глобальной переменной и перед началом работы считывается из dbf
2. Все алгоритмы загонялись в функцию, возвращающую количество чисел в наборе. Шаблон функции:
(84) ну, с учётом что исходные строки длиной <40, и что ограничение на дробную часть в 20 знаков.
можно добавить Лев(Стр,20) и Прав(Стр,20)
&НаКлиенте
Процедура ПолучениеДлиныСтроки ( Команда )
Длина_Строки_Число = СтрДлина ( "АБВГД" ); // 5 (символов)
&НаКлиенте
Процедура ПолучениеЧастиСтроки ( Команда )
ВычисляемаяСтрока = "1С Предприятие 8.3" ;
// N символов слева
Первые_два_символа = Лев ( ВычисляемаяСтрока , 2 ); // 1С
// N символов справа
Последние_три_символа = Прав ( ВычисляемаяСтрока , 3 ); // 8.3
// N символов из середины (с 4-го символа получим 11 символов)
Средние_символы = Сред ( ВычисляемаяСтрока , 4 , 11 ); // Предприятие
&НаКлиенте
Процедура ПолучениеЧислаВхожденийТекстаВСтроку ( Команда )
ВычисляемаяСтрока = "Между нами провода да да да да да. И ты сказала да да да." ;
Количество_вхождений = СтрЧислоВхождений ( ВычисляемаяСтрока , "да" ); // 8
&НаКлиенте
Процедура ПолучениеКодаСимвола ( Команда )
Код_из_символа = КодСимвола ( "C" ); // 67 (Латиница)
Код_первого_символа_в_строке = КодСимвола ( "Артур" ); // 1040 (Кирилица)
Код_пятого_символа_в_строке = КодСимвола ( "ABCDEFG" , 5 ); //69 (Латиница)
Символ_из_кода = Символ ( 67 ); // "A" (Латиница)
&НаКлиенте
Процедура ПреобразованиеВРегистр ( Команда )
//Регистры (верхний, нижний, титульный)
ВычисляемаяСтрока = "У лукоморья Дуб зелёный" ;
Преобразование_в_Верх_регистр = ВРег ( ВычисляемаяСтрока ); // У ЛУКОМОРЬЯ ДУБ ЗЕЛЁНЫЙ
Преобразование_в_Нижн_регистр = НРег ( ВычисляемаяСтрока ); // у лукоморья дуб зелёный
Преобразование_в_Титл_регистр = ТРег ( ВычисляемаяСтрока ); // У Лукоморья Дуб Зелёный
&НаКлиенте
Процедура ПреобразованиеСтрокиВЧисло ( Команда )
фЧисло = Число ( "987.65" ); // 987,65
фЧисло = Число ( "987,65" ); // 987,65
фЧисло = 100 + "24" ; // 124
//Для сложения числа и строки для получения строки:
фСтрока = Строка ( 100 ) + "24" ; // "10024"
&НаКлиенте
Процедура ПоискТекстаВСтроке ( Команда )
ВычисляемаяСтрока = "1С Предприятие 8.3" ;
ТекущийИндекс = Найти ( ВычисляемаяСтрока , "1С" ); // 1
&НаКлиенте
Процедура ПроверкаНаПустуюСтроку ( Команда )
ВычисляемаяСтрока = " " ;
Если ПустаяСтрока ( ВычисляемаяСтрока ) Тогда
// Т.е. может содержать только незначащие символы (например: Пробелы или Переносы)
Сообщить ( "Эта строка пустая!" );
КонецЕсли;
&НаКлиенте
Процедура ПроверкаНачалаИКонцаСтроки ( Команда )
// СтрНачинаетсяС - это проверка начала строки - со слова "Как"
РезультатПроверки = СтрНачинаетсяС ( "Как хорошо жить" , "Как" ); // Истина
// СтрЗаканчиваетсяНа - это проверка конца строки: на слово "хорошо"
РезультатПроверки = СтрЗаканчиваетсяНа ( "Как хорошо жить" , "хорошо" ); // Ложь
&НаКлиенте
Процедура ПереводСтрокиНаРазныеЯзыки ( Команда )
РезультатПеревода = НСтр ( "ru = 'Как дела?'; en = 'How are you?'" ); // зависит от установленного языка
Операции с многострочной строкой (с переносами) в 1С 8.3:&НаКлиенте
Процедура МногострочнаяСтрока ( Команда )
//Вставка переноса в строку
ВычисляемаяСтрока =
"Оплата по договору №1" + Символы . ПС + //1-я строка
"Контрагент ""Новая жизнь""" + Символы . ПС + //2-я строка (если нужно использовать " в строке то, используются двойные кавычки "")
"Сумма 1000 руб. с НДС 20%" ; //3-я строка
Результат_число_строк = СтрЧислоСтрок ( ВычисляемаяСтрока ); // 3(строки)
Результат_2_строка = СтрПолучитьСтроку ( ВычисляемаяСтрока , 2 )); // "Контрагент ""Новая жизнь"""
&НаКлиенте
Процедура РазбиениеСтрокиСРазделителями1 ( Команда ) //Пример №1
Разделитель = ";" ;
СтрокиСРазделителем = СтрЗаменить ( "2020; 2021; 2022" , Разделитель , Символы . ПС );
Для А = 1 По СтрЧислоСтрок ( СтрокиСРазделителем ) Цикл
Сообщить ( СтрПолучитьСтроку ( СтрокиСРазделителем , А ));
КонецЦикла;
&НаКлиенте
Процедура РазбиениеСтрокиСРазделителями2 ( Команда ) //Пример №2 (доступно с платформы 8.3.6.1977)
// Параметры СтрРазделить: Строка, Разделитель(символы), Булево (по умолчанию - Истина - включать в результат пустые строки)
РезультатМассив = СтрРазделить ( "2020; 2021; 2022" , ";" ); // Массив с элементами [0] = "2020", [1] = "2021 ", [2] = "2022"
// Существует обратная функция СтрСоединить, которая наоборот преобразует массив к строке.
РезультатСтрока = СтрСоединить ( РезультатМассив , ";" ); // Строка "2020; 2021; 2022"
Читайте также: