Форум на Kuban.ru (http://forums.kuban.ru/)
-   Территория 1С (http://forums.kuban.ru/f1040/)
-   -   Извлечь число из строки (http://forums.kuban.ru/f1040/izvlech-_chislo_iz_stroki-8827752.html)

Torin 02.03.2019 07:45

Извлечь число из строки
 
Исходные данные
Строка содержимое " комиссия: 11 343.91. актив"

Необходимо получить (извлечь) число

11343.91

Прошу поделится примером

GariPortman 02.03.2019 08:17

Цифры = "1234567890.";
Для НомСимвола = 1 По СтрДлина(Слово) Цикл
ТекущийСимвол =Сред(Слово, НомСимвола, 1);
Если не Найти(Цифры, ТекущийСимвол) = 0 Тогда
ЧислоСтр = ЧислоСтр+ТекущийСимвол;

Ну и естественно лишняя точкой(а может быть запятая) или цифра в тексте приведет к неправильному результату.

USSR 02.03.2019 10:10

Можно просто удалить символ разделителя триад и затем преобразовать строку в число

GariPortman 02.03.2019 11:18

У него не только триады. " комиссия: 11 343.91. актив". Ещё убирать последнюю точку или проверять что бы точка была между цифрам. А потом окажется что вариантов текста гораздо больше.

USSR 02.03.2019 11:49

(3)Я комиссию с активом упустил, еще не совсем проснулся Вариантов море. Твой способ более универсальный, спору нет. А так, можно например ".актив" и "комиссия" заменить на "". Не бином Ньютона

Ткачик 02.03.2019 12:15

Эх, 1Сники...

Даже из уже поставленных условий [b]программисту[/b] должно быть ясно: [b]одним циклом не обойтись[/b]. Алгоритм должен быть таким:
1. В цикле ищем [b]первую[/b] цифру (0123456789) в строке.
2. Во втором цикле формируем выходную строку по примеру из (1). Цикл начинаем с позиции, найденной в п.1 и прерываем на первом же [b]нецифровом[/b] символе (кроме пробела, его просто пропускаем)
3. Проверяем этот нецифровой символ, если это [b]точка[/b] - проверяем [b]следующие два[/b] символа: где гарантия, что не будет строки [b]" комиссия: 11 343. актив"[/b]? Если эти символы - цифры, то к выходной строке добавляем точку и эти два символа (дробная часть).

Работа программиста на этом закончена, а код пусть [b]кодеры[/b] напишут.

USSR 02.03.2019 12:39

(5)надо смотреть задачу, если строка всегда имеет такой формат, то я бы все таки просто вырезал лишнее слева и справа, либо СтрЗаменить, либо Сред,Лев,Прав
А вообще надо смотреть откуда такие строки появились, может там поправить )

GariPortman 02.03.2019 12:49

1. Программиста, предлагающего лишний цикл переименовать в кодера. 2. После цикла из (1) в ЧислоСтр проверить последний символ и если это "."- то вернуть строку без последнего символа.

Ткачик 02.03.2019 13:19

[quote=Begemot;46541695]После цикла из (1) в ЧислоСтр проверить последний символ и если это "."- то вернуть строку без последнего символа.[/quote] Кодера, предлагающего такое, переименовать в "г...внокодера". Потому что от этого всего один шаг до эпического:

Если Слово=" комиссия: 11 343.91. актив" Тогда
ЧислоСтр="11 343.91";
КонецЕсли;

Программист же [b]обязан[/b] предположить: а если там окажется [b]две[/b] точки? Или три? Надеюсь, идея понятна? Если нет, то объясняю: по уму эти точки надо удалять [b]в цикле[/b].

А если не исключать и наличие точек в начале строки - [b]в двух[/b] циклах. Ы?

P.S. Хотя, конечно, можно извратиться:

Цифры = "1234567890";
Для НомСимвола = 1 По СтрДлина(Слово) Цикл
ТекущийСимвол =Сред(Слово, НомСимвола, 1);
Если ТекущийСимвол = "." Тогда
ЧислоСтр = ЧислоСтр+" ";
ИначеЕсли Найти(Цифры, ТекущийСимвол) > 0 Тогда
ЧислоСтр = ЧислоСтр+ТекущийСимвол;
КонецЕсли;
КонецЦикла;
ЧислоСтр = СтрЗаменить(СокрЛП(ЧислоСтр)," ",".");

Но это, как говорится, "на любителя".

USSR 02.03.2019 13:34

ПРИКЛАДНОЙ программст не Ванга, ему не надо ничего предполагать. Есть контекст задачи и в нем работаем. Изменится контекст, изменится и решение. И в этом нет никакого позора. Дали такое задание, так решили. Это не значит, что решили плохо, это значит, что решили в контексте требований заказчика. А если в строке появятся другие символы, то это проблема заказчик. Наш заказчик в (1) именно так обозначил проблему, а не как то иначе. Будет иначе, будут иные решения

Блондинка в шок 02.03.2019 14:02

[quote=Ткачик;46541582]3. Проверяем этот нецифровой символ, если это точка - проверяем следующие [b]два [/b]символа. Если эти символы - цифры, то к выходной строке добавляем точку и эти два символа (дробная часть).[/quote] п.п.1-2 согласна, этот пункт - нет. Вес - это, как правило, три символа после запятой, курс может быть и шесть символов. Так что не проверяем не "[em]два следующих символа[/em]", а "[em]до упора[/em]", т.е. пока не закончатся цифры после [b]первой [/b]точки.
а так в целом я за вариант в (5)

GariPortman 02.03.2019 14:29

[quote=Ткачик;46541769]Кодера, предлагающего такое, переименовать в "г...внокодера". Потому что от этого всего один шаг до эпического:[/quote] Зацепил значит. Это от твоих двух циклов чем то попахивает.
Все что ты написал в (5) можно сделать в одном цикле. Это раз.
На поставленную задачу в "0" я ответ дал. Это два
Ну и три. Если вопрос стоит сделать универсальную функцию, то твой вариант от универсальной функции так же далек. Он не предполагает что число может быть вида 123.1 или 123.123 или вида .123
Так что если учите кодить учите правильно.

Ткачик 02.03.2019 14:35

[quote=Блондинка в шок;46541860]Так что не проверяем не "два следующих символа", а "до упора"[/quote] Верное замечание, это уже я поддался менталитету "ПРИКЛАДНОГО программиста" и сузил задачу до суммы - то есть, как она была поставлена автором ветки.

А вообще, можно написать решение задачи и [b]в одном цикле[/b], надо только на каждом шаге проверять результат и точку. Например, через ЗначениеЗаполнено(ЧислоСтр) и логическую переменную ЕстьТочка.

То есть, пока ЗначениеЗаполнено(ЧислоСтр)=Ложь - пропускаем всё, кроме цифр.
Как только стало ЗначениеЗаполнено(ЧислоСтр)=Истина - проверяем и точку, если совпадает (первая) - ЕстьТочка=Истина.
Если цифра - добавляем к строке, но сначала проверяем ЕстьТочка - если Истина, то перед цифрой добавляем и точку.
Первая же НЕ цифра и НЕ точка при ЗначениеЗаполнено(ЧислоСтр)=Истина - прерываем цикл.

Там еще парочка проверок всплывет, но писать идеальный код ради "победы" на форуме - лениво.

Ткачик 02.03.2019 14:44

[quote=Begemot;46541919]Зацепил значит.[/quote] Зацепил, зацепил, не переживай.
[quote=Begemot;46541919]На поставленную задачу в "0" я ответ дал. Это два[/quote] Поставленную задачу решает и код из (8) Причем, [b]оба[/b] варианта. ;-P

Добавлять ничего не стану - в (12) все сказано.

GariPortman 02.03.2019 14:54

[quote=Ткачик;46541948]Поставленную задачу решает и код из (8) Причем, оба варианта. ;-P[/quote]Не оба а все три варианта.

Torin 02.03.2019 17:46

Коллеги спасибо всем большое, отдельное спасибо [b]Begemot[/b] и [b]Ткачик[/b]

EarlyBird 02.03.2019 21:19

вообще-то, программист 1Сник не парится, когда нужно написать ещё один цикл для обхода строки.
потому что программист 1Сник всегда знает ресурсоёмкость своего алгоритма.
в данном случае добавление ещё одного цикла - никак не увеличит ресурсоёмкость (никак - от слова совсем).
Ни на миллионную долю секунды.
это ведь всего лишь ещё один обход строки ограниченной длины.
А не обход всех записей регистра, к примеру.

EarlyBird 02.03.2019 21:20

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

buh 03.03.2019 21:42

RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.Pattern = "\d*\.+\d*";
ИсходныйТекст = " комиссия: 11 343.91. актив";
Сообщить(RegExp.Execute(СтрЗаменить(ИсходныйТекст," ","")).Item(0).Value);

Блондинка в шок 03.03.2019 22:25

18-buh > увы


[quote]Правительство Ростовской области

Постановление
от 13.12.2018 № 803
г. Ростов-на-Дону

Об утверждении Плана мероприятий по переходу органов исполнительной власти Ростовской области на использование отечественного офисного программного обеспечения на период до 2020 года[/quote]

это не шутка:
[url]http://www.donland.ru/documents/Ob-utverzhdenii-Plana-meropriyatijj-po-perekhodu-organov-ispolnitelnojj-vlasti-Rostovskojj-oblasti-na-ispolzovanie-otechestvennogo-ofisnogo-?pageid=128483&mid=134977&itemId=28300[/url]


вот нету там COM-Объектов, в этом якобы "[em]отечественном[/em]" :))) ПО

GariPortman 03.03.2019 22:49

18-buh >Ещё один способ одеть трусы через голову.

GariPortman 04.03.2019 00:19

+20 НО потенциально рабочий, в отличии от варианта Ткачика в (5).

Ткачик 04.03.2019 01:39

(21) М-да. Вот уж кого я не просто "зацепил", а подвесил: автор уже получил все, что хотел, а он все чего-то доказывает.

GariPortman 04.03.2019 08:19

(22) "Не зацепил а подвесил". Батенька - да вы нас просто расмешили. И смешить продолжаете. Извергли на всех огромный ушак г@вна. Назвали все предложенные варианты "говнокодом" а всех "говнокодерами". И ... представили публики своё "творение". Алгоритм поиска [b]чисел[/b], основннный на [quote=Ткачик;46541582]1. В цикле ищем первую цифру (0123456789) в строке.[/quote]. Вот только конфуз вышел. Забыли при про минус, тире и точку. Знаки, которые могут быть перед "первой цифрой". И тут уже двумя циклами не обойдемся. Нужен третий - "в лево" от "первой цифры".
Не менее спорный и 2 пункт "супер" алгоритма. [quote=Ткачик;46541582]2. Во втором цикле формируем выходную строку по примеру из (1). Цикл начинаем с позиции, найденной в п.1 и прерываем на первом же нецифровом символе (кроме пробела, его просто пропускаем)[/quote]
А как же разделители триад? Нет если [quote=Ткачик;46541769]Программист же обязан предположить: а если там окажется две точки? Или три?[/quote] программмсит обязан предположить про точки - то забыть про триады он ни как не может.
Так что это фиаско алгоритма. Ну или попробуй убедить в обратном. Покупаем попкорн.

Пудель 11.03.2019 07:43

если ты не прикладной - нарисуй вагон другой ).
количество циклов - вторично.
красота кода - должна чувствоваться интуитивно нутром, а не подсчитываться по арифметическим критериям, имхо.

а слабо вообще без циклов? )


Текущее время: 01:57. Часовой пояс GMT +3.