Вытащить числа, но при этом они могут быть дробными и целыми

1. Nauchus 20.12.24 20:27 Сейчас в теме
Моя задача состоит в том чтобы вытащить числа, но при этом они могут быть дробными и целыми.
Пример 32.342.324.34 - 32342324.34 и тому подобные, вводятся они именно с точками. "dsfhs12.432.234.32sdfsdf21.434dsfsd4.34fsdfsdf334.342.34"Так вот нужно вытащить числа и сложить учитывая что они дробные и целые, впал в ступор в моменте того как к числам добавились миллионы, то-есть больше 2 точек
По теме из базы знаний
Найденные решения
9. mkalimulin 1491 20.12.24 22:55 Сейчас в теме
(8) И вот, что я получил

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

Вот пример кода на 1С, реализующий данную задачу:

```1C
Функция ИзвлечьЧислаИзСтроки(ИсходнаяСтрока) Экспорт
    МассивЧисел = Новый Массив;
    ТекущееЧисло = "";
    
    Для И = 1 По СтрДлина(ИсходнаяСтрока) Цикл
        Символ = Сред(ИсходнаяСтрока, И, 1);
        Если (Символ >= "0" И Символ <= "9") Или Символ = "." Тогда
            ТекущееЧисло = ТекущееЧисло + Символ;
        Иначе
            Если ТекущееЧисло <> "" Тогда
                Число = ОбработатьЧислоСтроку(ТекущееЧисло);
                Если Число <> Неопределено Тогда
                    МассивЧисел.Добавить(Число);
                КонецЕсли;
                ТекущееЧисло = "";
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    
    Если ТекущееЧисло <> "" Тогда
        Число = ОбработатьЧислоСтроку(ТекущееЧисло);
        Если Число <> Неопределено Тогда
            МассивЧисел.Добавить(Число);
        КонецЕсли;
    КонецЕсли;

    Возврат МассивЧисел;
КонецФункции

Функция ОбработатьЧислоСтроку(СтрокаЧисла)
    ЧастиЧисла = СтрРазделить(СтрокаЧисла, ".");
    КоличествоЧастей = ЧастиЧисла.Количество();
    
    Если КоличествоЧастей = 0 Тогда
        Возврат Неопределено;
    КонецЕсли;
    
    ПоследняяЧасть = ЧастиЧисла[КоличествоЧастей - 1];
    Если СтрДлина(ПоследняяЧасть) = 2 Тогда
        ДробнаяЧасть = ПоследняяЧасть;
        ЦелыеЧасти = Новый Массив;
        Для И = 0 По КоличествоЧастей - 2 Цикл
            ЦелыеЧасти.Добавить(ЧастиЧисла[И]);
        КонецЦикла;
    Иначе
        ДробнаяЧасть = "";
        ЦелыеЧасти = ЧастиЧисла;
    КонецЕсли;
    
    ЦелаяЧасть = "";
    Для Каждого Часть Из ЦелыеЧасти Цикл
        ЦелаяЧасть = ЦелаяЧасть + Часть;
    КонецЦикла;
    
    Если ЦелаяЧасть = "" Тогда
        ЦелаяЧасть = "0";
    КонецЕсли;
    
    Если ДробнаяЧасть <> "" Тогда
        ПолноеЧислоСтрока = ЦелаяЧасть + "." + ДробнаяЧасть;
    Иначе
        ПолноеЧислоСтрока = ЦелаяЧасть;
    КонецЕсли;
    
    Попытка
        Результат = Число(ПолноеЧислоСтрока);
    Исключение
        Результат = Неопределено;
    КонецПопытки;
    
    Возврат Результат;
КонецФункции
Показать

```

**Объяснение работы кода:**

- **Функция `ИзвлечьЧислаИзСтроки`** последовательно обходит каждый символ исходной строки.
- Если символ является цифрой или точкой, он добавляется к текущей собираемой подстроке числа.
- Если встречается любой другой символ, и если в настоящее время собирается число, эта подстрока передается на обработку в функцию `ОбработатьЧислоСтроку`, результат добавляется в массив чисел, и текущая подстрока числа очищается.
- **Функция `ОбработатьЧислоСтроку`** принимает строку, представляющую число в специальном формате.
- Строка разделяется по точкам на массив частей.
- Если последняя часть имеет длину 2, она рассматривается как дробная часть, остальные части объединяются в целую часть.
- Если длина последней части не равна 2, все части объединяются в целую часть, дробной части нет.
- Объединенные части преобразуются в число. Если преобразование успешно, число возвращается, иначе возвращается `Неопределено`.

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

```1C
Строка = "dsfhs12.432.234.32sdfsdf21.434dsfsd4.34fsdfsdf334.342.34";
МассивЧисел = ИзвлечьЧислаИзСтроки(Строка);
Для Каждого Число Из МассивЧисел Цикл
Сообщить(Число);
КонецЦикла;
```

**Ожидаемый вывод:**

- 12432234.32
- 21434
- 4.34
- 334342.34

Таким образом, данный код извлекает все числа из строки в соответствии с заданным форматом, без использования регулярных выражений.
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. Nauchus 20.12.24 20:32 Сейчас в теме
Регулярное выражение нельзя использовать
3. user2107191 20.12.24 20:40 Сейчас в теме
Мы гордимся, что ты заслужил такое достойное задание! И, конечно же, верим в тебя!!!
4. Nauchus 20.12.24 20:43 Сейчас в теме
5. mkalimulin 1491 20.12.24 22:36 Сейчас в теме
21.434 дробное или целое?
6. Nauchus 20.12.24 22:43 Сейчас в теме
(5)Дроби только десятичные, речь идет о копейках, то есть если после точки три символа это не дробь
8. mkalimulin 1491 20.12.24 22:54 Сейчас в теме
(6) 0.434 тоже десятичная дробь, и 0.54895798345678943 десятичная дробь
Но не суть. Я понял, что ты имеешь в виду. В таких ситуациях надо спрашивать у state-of-art LLM и сразу получать работающий код, а не тратить время на форуме, где тебе если и ответят, то далеко не так быстро.
В порядке исключения, вот что я спросил у o1-preview:

Из строки следующего вида: "dsfhs12.432.234.32sdfsdf21.434dsfsd4.34fsdfsdf334.342.34" вытащить все числа. Сложность в том, что в качестве разделителя разрядов и разделителя дробной части указывается точка "." Например, число 32342324.34 записывается как 32.342.324.34, а число 21434 как 21.434 Числа представлены в денежном формате. Это означает, что дробная часть имеет только два знака, если она есть.
Нужен код на языке 1С без использования регулярных выражений
9. mkalimulin 1491 20.12.24 22:55 Сейчас в теме
(8) И вот, что я получил

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

Вот пример кода на 1С, реализующий данную задачу:

```1C
Функция ИзвлечьЧислаИзСтроки(ИсходнаяСтрока) Экспорт
    МассивЧисел = Новый Массив;
    ТекущееЧисло = "";
    
    Для И = 1 По СтрДлина(ИсходнаяСтрока) Цикл
        Символ = Сред(ИсходнаяСтрока, И, 1);
        Если (Символ >= "0" И Символ <= "9") Или Символ = "." Тогда
            ТекущееЧисло = ТекущееЧисло + Символ;
        Иначе
            Если ТекущееЧисло <> "" Тогда
                Число = ОбработатьЧислоСтроку(ТекущееЧисло);
                Если Число <> Неопределено Тогда
                    МассивЧисел.Добавить(Число);
                КонецЕсли;
                ТекущееЧисло = "";
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    
    Если ТекущееЧисло <> "" Тогда
        Число = ОбработатьЧислоСтроку(ТекущееЧисло);
        Если Число <> Неопределено Тогда
            МассивЧисел.Добавить(Число);
        КонецЕсли;
    КонецЕсли;

    Возврат МассивЧисел;
КонецФункции

Функция ОбработатьЧислоСтроку(СтрокаЧисла)
    ЧастиЧисла = СтрРазделить(СтрокаЧисла, ".");
    КоличествоЧастей = ЧастиЧисла.Количество();
    
    Если КоличествоЧастей = 0 Тогда
        Возврат Неопределено;
    КонецЕсли;
    
    ПоследняяЧасть = ЧастиЧисла[КоличествоЧастей - 1];
    Если СтрДлина(ПоследняяЧасть) = 2 Тогда
        ДробнаяЧасть = ПоследняяЧасть;
        ЦелыеЧасти = Новый Массив;
        Для И = 0 По КоличествоЧастей - 2 Цикл
            ЦелыеЧасти.Добавить(ЧастиЧисла[И]);
        КонецЦикла;
    Иначе
        ДробнаяЧасть = "";
        ЦелыеЧасти = ЧастиЧисла;
    КонецЕсли;
    
    ЦелаяЧасть = "";
    Для Каждого Часть Из ЦелыеЧасти Цикл
        ЦелаяЧасть = ЦелаяЧасть + Часть;
    КонецЦикла;
    
    Если ЦелаяЧасть = "" Тогда
        ЦелаяЧасть = "0";
    КонецЕсли;
    
    Если ДробнаяЧасть <> "" Тогда
        ПолноеЧислоСтрока = ЦелаяЧасть + "." + ДробнаяЧасть;
    Иначе
        ПолноеЧислоСтрока = ЦелаяЧасть;
    КонецЕсли;
    
    Попытка
        Результат = Число(ПолноеЧислоСтрока);
    Исключение
        Результат = Неопределено;
    КонецПопытки;
    
    Возврат Результат;
КонецФункции
Показать

```

**Объяснение работы кода:**

- **Функция `ИзвлечьЧислаИзСтроки`** последовательно обходит каждый символ исходной строки.
- Если символ является цифрой или точкой, он добавляется к текущей собираемой подстроке числа.
- Если встречается любой другой символ, и если в настоящее время собирается число, эта подстрока передается на обработку в функцию `ОбработатьЧислоСтроку`, результат добавляется в массив чисел, и текущая подстрока числа очищается.
- **Функция `ОбработатьЧислоСтроку`** принимает строку, представляющую число в специальном формате.
- Строка разделяется по точкам на массив частей.
- Если последняя часть имеет длину 2, она рассматривается как дробная часть, остальные части объединяются в целую часть.
- Если длина последней части не равна 2, все части объединяются в целую часть, дробной части нет.
- Объединенные части преобразуются в число. Если преобразование успешно, число возвращается, иначе возвращается `Неопределено`.

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

```1C
Строка = "dsfhs12.432.234.32sdfsdf21.434dsfsd4.34fsdfsdf334.342.34";
МассивЧисел = ИзвлечьЧислаИзСтроки(Строка);
Для Каждого Число Из МассивЧисел Цикл
Сообщить(Число);
КонецЦикла;
```

**Ожидаемый вывод:**

- 12432234.32
- 21434
- 4.34
- 334342.34

Таким образом, данный код извлекает все числа из строки в соответствии с заданным форматом, без использования регулярных выражений.
16. user1936660 21.12.24 00:22 Сейчас в теме
(9) На, дообучай свой фетиш
Функция ИзвлечьЧислаИзСтроки(ИсходнаяСтрока)
	
	ТипЧисло = Новый ОписаниеТипов("Число");
	
	Разделители = СтрРазделить(ИсходнаяСтрока, "1234567890.", Ложь);
	НаборЧисел = СтрРазделить(ИсходнаяСтрока, СтрСоединить(Разделители, ""), Ложь);
	
	Для Индекс = 0 По НаборЧисел.ВГраница() Цикл
		ЧастиЧисла = СтрРазделить(НаборЧисел[Индекс], ".", Ложь);
		ИндексПоследнейЧасти = ЧастиЧисла.ВГраница();
		
		ДробнаяЧасть = ЧастиЧисла[ИндексПоследнейЧасти];
		ДлинаДробнойЧасти = СтрДлина(ДробнаяЧасть);
		
		Если ДлинаДробнойЧасти = 2 И ИндексПоследнейЧасти > 0 Тогда
			ЧастиЧисла.Удалить(ИндексПоследнейЧасти);
		Иначе
			ДробнаяЧасть = "";
		КонецЕсли;
		
		ЦелаяЧасть = СтрСоединить(ЧастиЧисла, "");
		
		НаборЧисел[Индекс] = ТипЧисло.ПривестиЗначение(ЦелаяЧасть)
			+ ТипЧисло.ПривестиЗначение(ДробнаяЧасть) / Pow(10, ДлинаДробнойЧасти);
	КонецЦикла;
	
	Возврат НаборЧисел;
	
КонецФункции
Показать


И это я твоё поделие еще на граничные случаи не проверял, типа пустых строк и строк без цифр
Sashares; +1 Ответить
19. mkalimulin 1491 21.12.24 01:32 Сейчас в теме
(16) Ты знаешь, что такое Codeforces?
10. mkalimulin 1491 20.12.24 22:56 Сейчас в теме
(6) Делай, как все сейчас делают. Не занимайся ерундой
11. Nauchus 20.12.24 22:58 Сейчас в теме
13. user1936660 20.12.24 23:51 Сейчас в теме
(10)
как все сейчас делают
Они с тобой в одной комнате?
Sashares; +1 Ответить
7. Nauchus 20.12.24 22:48 Сейчас в теме
12.432.234.32 = 12432234.32
21.434 = 21434
4.34 = 4.34
334.342.34 = 334342.34
(5)
17. user1936660 21.12.24 00:23 Сейчас в теме
(7) Будет весьма забавно, если ты принесешь этот код как "выполненое задание" его автору.
12. user1936660 20.12.24 23:44 Сейчас в теме
(9)
Для И = 1 По СтрДлина(ИсходнаяСтрока) Цикл 
Восхитительно
14. mkalimulin 1491 21.12.24 00:03 Сейчас в теме
(12) Ну возьми с полки пирожок )))
15. user1936660 21.12.24 00:13 Сейчас в теме
(14)
с полки пирожок
Если бы ты их оттуда сам не забирал, было бы совсем хорошо.

надо спрашивать у state-of-art LLM и сразу получать работающий код,
Точно-точно.
18. mkalimulin 1491 21.12.24 01:12 Сейчас в теме
(15) Точно-точно. Сам проверь. Я же написал: "в порядке исключения". Обычно предлагаю людям проверять самостоятельно. Используй о1 вместо o1-preview и получишь рабочий код
20. mkalimulin 1491 21.12.24 11:29 Сейчас в теме
(15) Вот o1-mini выдает:
Вот пример кода на языке 1С, который выполняет требуемую задачу без использования регулярных выражений. Код проходит по исходной строке, извлекает потенциальные числовые подстроки, проверяет их на соответствие денежному формату и собирает все найденные числа в массив.

```1c
Процедура ИзвлечьЧисла(ИсходнаяСтрока)
    // Массив для хранения найденных чисел
    НайденныеЧисла = Новый Массив;

    ДлинаСтроки = СтрДлина(ИсходнаяСтрока);
    Начало = 0;

    Для Индекс = 1 По ДлинаСтроки Цикл
        Символ = Сред(ИсходнаяСтрока, Индекс, 1);
        Если Не (Символ >= "0" И Символ <= "9") И Символ <> "." Тогда
            // Если текущий символ не цифра и не точка, завершаем текущий поиск
            Если Начало > 0 Тогда
                // Извлекаем подстроку
                Подстрока = Сред(ИсходнаяСтрока, Начало, Индекс - Начало);
                Если ПроверитьЧисло(Подстрока) Тогда
                    // Добавляем в массив
                    НайденныеЧисла.Добавить(Подстрока);
                КонецЕсли;
                Начало = 0;
            КонецЕсли;
        Иначе
            // Если текущий символ цифра или точка
            Если Начало = 0 Тогда
                Начало = Индекс;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;

    // Проверка последней подстроки, если строка заканчивается на число
    Если Начало > 0 Тогда
        Подстрока = Сред(ИсходнаяСтрока, Начало, ДлинаСтроки - Начало + 1);
        Если ПроверитьЧисло(Подстрока) Тогда
            НайденныеЧисла.Добавить(Подстрока);
        КонецЕсли;
    КонецЕсли;

    // Вывод найденных чисел
    Для Каждого Число Из НайденныеЧисла Цикл
        Сообщить(Число);
    КонецЦикла;
КонецПроцедуры

Функция ПроверитьЧисло(СтрокаЧисла) Экспорт
    // Проверяет, соответствует ли строка денежному формату
    КоличествоТочек = 0;
    Длина = СтрДлина(СтрокаЧисла);
    
    Для i = 1 По Длина Цикл
        Символ = Сред(СтрокаЧисла, i, 1);
        Если Символ = "." Тогда
            КоличествоТочек = КоличествоТочек + 1;
        ИначеЕсли Не (Символ >= "0" И Символ <= "9") Тогда
            Возврат Ложь;
        КонецЕсли;
    КонецЦикла;

    Если КоличествоТочек = 0 Тогда
        // Целое число
        Возврат Истина;
    Иначе
        // Проверяем, что после последней точки ровно два символа
        ПозицияПоследнейТочки = НайтиПоследнююТочку(СтрокаЧисла);
        Если ПозицияПоследнейТочки = 0 Тогда
            Возврат Ложь;
        КонецЕсли;
        Если (Длина - ПозицияПоследнейТочки) <> 3 Тогда
            Возврат Ложь;
        КонецЕсли;
        // Проверяем, что последние два символа после точки — цифры
        ПоследниеДва = Сред(СтрокаЧисла, ПозицияПоследнейТочки + 1, 2);
        Для i = 1 По 2 Цикл
            Символ = Сред(ПоследниеДва, i, 1);
            Если Не (Символ >= "0" И Символ <= "9") Тогда
                Возврат Ложь;
            КонецЕсли;
        КонецЦикла;
        Возврат Истина;
    КонецЕсли;
КонецФункции

Функция НайтиПоследнююТочку(СтрокаЧисла) Экспорт
    // Возвращает позицию последней точки в строке
    Длина = СтрДлина(СтрокаЧисла);
    Для i = Длина По 1 Шаг -1 Цикл
        Если Сред(СтрокаЧисла, i, 1) = "." Тогда
            Возврат i;
        КонецЕсли;
    КонецЦикла;
    Возврат 0;
КонецФункции
Показать

// Пример вызова процедуры
ИсходнаяСтрока = "dsfhs12.432.234.32sdfsdf21.434dsfsd4.34fsdfsdf334.342.34";
ИзвлечьЧисла(ИсходнаяСтрока);
```

### Пояснение к коду:

1. **Основная процедура `ИзвлечьЧисла`**:
- **Итерация по строке**: Проходим по каждому символу исходной строки.
- **Определение начала числа**: Если символ является цифрой или точкой и мы еще не внутри числа, помечаем начало потенциального числа.
- **Завершение числа**: Когда встречается символ, не являющийся цифрой или точкой, извлекаем подстроку с числом и проверяем её.
- **Проверка последней подстроки**: После окончания цикла проверяем, не осталось ли число в конце строки.
- **Вывод результатов**: Все найденные корректные числовые подстроки выводятся с помощью `Сообщить`.

2. **Функция `ПроверитьЧисло`**:
- **Проверка символов**: Убедимся, что строка содержит только цифры и точки.
- **Определение формата**:
- Если точек нет, это целое число.
- Если точки есть, проверяем, что после последней точки ровно два цифры (соответствует дробной части в денежном формате).
- **Проверка дробной части**: Убедимся, что после последней точки действительно находятся две цифры.

3. **Функция `НайтиПоследнююТочку`**:
- Проходит строку с конца к началу и возвращает позицию последней точки. Если точек нет, возвращает 0.

### Результат выполнения:

При запуске данного кода для строки `"dsfhs12.432.234.32sdfsdf21.434dsfsd4.34fsdfsdf334.342.34"` будут найдены и выведены следующие числа:

- `12.432.234.32`
- `21.434`
- `4.34`
- `334.342.34`

Эти строки соответствуют заданному денежному формату с учетом требований к разделителям разрядов и дробной части.
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот