Чем расщепить или "СтрРазделить() VS РазложитьСтрокуВМассивПодстрок()" ?

06.06.19

Разработка - Механизмы платформы 1С

Сравнение методов по "расщеплению" строк Какой и когда использовать? Платформенный или БСП? Приходим к выводу - и тот и другой.

В случаях, когда нужно разбить строку на части, чаще всего используется один из методов:

  1. СтрРазделить() - платформенный метод
  2. РазложитьСтрокуВМассивПодстрок() - функция общего модуля БСП

 

Всеми рекомендуется использовать СтрРазделить(), так как это платформенный и более оптимизированный метод. Однако, при этом часто забывают, что он не полностью идентичен второму. И в некоторых случаях применить его не получится.

 


Разберём нагляднее параметры по-порядку:

СтрРазделить(<Строка>, <Разделитель>, <ВключатьПустые>)

РазложитьСтрокуВМассивПодстрок(<Строка>, <Разделитель>, <ПропускатьПустыеСтроки>, <СокращатьНепечатаемыеСимволы>)

 

  1. <Строка>
    Тут всё понятно. Строка, которую нужно разделить.
  2. <Разделитель>
    Вроде тоже ясно. Строка, которая является разделителем.
    Однако. Этот параметр оба метода используют по-разному, когда его значение больше, чем один символ.

    У СтрРазделить() каждый символ в параметре является отдельным разделителем. В то время как в РазложитьСтрокуВМассивПодстрок() он цельный.

    Разницу понять легче нагляднее на примере (для удобства исключим пустые элементы в результате)
     
Результат   = РазложитьСтрокуВМассивПодстрок("а1б1в1", "б1");
//Результат = [а1;в1]

"б1" - цельный разделитель

Результат   = СтрРазделить("а1б1в1", "б1", Ложь);
//Результат = [а;в]

"б1" - набор из двух несвязанных разделителей. "б" и "1".

 

Выходит, что когда нам необходимо в качестве разделителя использовать некую строку, то используем метод РазложитьСтрокуВМассивПодстрок(). Ведь платформенный СтрРазделить() сработает иначе.
 

Так же интересная особенность. Если в этот параметр передать пустую строку, то СтрРазделить() вернёт массив с одним элементов (всей строкой). А РазложитьСтрокуВМассивПодстрок() уйдёт в небытие...


3 . <ВключатьПустые> и <ПропускатьПустыеСтроки>

Параметр хоть и схож, но, снова, не полностью идентичен.

Платформенный метод имеет два положения: Ложь или Истина. Либо результат метода будет содержать пустые строки, либо нет.

В то время, как метод БСП имеет чуть более расширенный функционал, а именно:

Если параметр не задан, то функция работает в режиме совместимости со своей предыдущей версией:
- для разделителя-пробела пустые строки не включаются в результат, для остальных разделителей пустые строки включаются в результат.
- если параметр Строка не содержит значащих символов или не содержит ни одного символа (пустая строка), то в случае разделителя-пробела результатом функции будет массив, содержащий одно значение "" (пустая строка), а при других разделителях результатом функции будет пустой массив.


Получается, если не передать параметр, то БСП сама решит догадаться, нужно ли сохранять пустые элементы или нет. По мне так, если нет необходимости, лучше всегда указывать конкретно логику, чтобы и самому не путаться и не путать других.

 

4. <СокращатьНепечатаемыеСимволы>

Данный параметр есть только в РазложитьСтрокуВМассивПодстрок().
Всё просто - нужно ли к каждому элементу массива применять СокрЛП (избавлять слева и справа всякие пробелы и переносы строк).

СтрРазделить() этого делать не умеет. Однако, замеры скорости показывают, что быстрее будет обойти циклом результат СтрРазделить(), чем использовать РазложитьСтрокуВМассивПодстрок().

 

Какие выводы?

В большинстве случаев при помощи СтрРазделить() можно сделать тоже самое, что и РазложитьСтрокуВМассивПодстрок(). В таких случаях нужно применять платформенный метод. Но:

  • Когда необходимо использовать разделитель, состоящий из строки, а не одного символа, берёмся за РазложитьСтрокуВМассивПодстрок()
  • Когда необходимо, чтобы элементы результата были обработаны СокрЛП(), делаем это сами постобработкой. Так будет быстрее.

 

Понять особенности методов будет полезно на практике. Но помнить не обязательно. Можно вместо этого использовать обёртку на подобии:

 

Функция СтрРазделитьРасширенная(Строка, Разделитель = ",", ВключатьПустые = Истина,
	СокращатьНепечатаемыеСимволы = Ложь, РазделительЕдинойСтрокой = Истина) Экспорт

	Если РазделительЕдинойСтрокой И СтрДлина(Разделитель) > 1 Тогда

		Результат = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(
		Строка, Разделитель, НЕ ВключатьПустые, СокращатьНепечатаемыеСимволы);

	Иначе

		Результат = СтрРазделить(Строка, Разделитель, ВключатьПустые);
		Если СокращатьНепечатаемыеСимволы Тогда
			Для Индекс = 0 По Результат.Количество()-1 Цикл
				Результат[Индекс] = СокрЛП(Результат[Индекс]);
			КонецЦикла;
		КонецЕсли;

	КонецЕсли;        

	Возврат Результат;

КонецФункции

строки БСП программирование матчасть

См. также

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Эта небольшая статья - некоторого рода шпаргалка по файловым потокам: как и зачем с ними работать, какие преимущества это дает.

23.06.2024    7455    bayselonarrend    20    

154

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пример использования «Сервисов интеграции» без подключения к Шине и без обменов.

13.03.2024    5946    dsdred    16    

80

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Все мы используем массивы в своем коде. Это один из первых объектов, который дают ученикам при прохождении обучения программированию. Но умеем ли мы ими пользоваться? В этой статье я хочу показать все методы массива, а также некоторые фишки в работе с массивами.

24.01.2024    17673    YA_418728146    26    

71

Перенос данных 1C Механизмы платформы 1С Системный администратор Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    11225    dsdred    44    

130

Механизмы платформы 1С Программист Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    23763    SeiOkami    48    

135

Механизмы платформы 1С Системный администратор Платформа 1С v8.3 Бесплатно (free)

Начиная с версии платформы 8.3.22 1С снимает стандартные блокировки БД на уровне страниц. Делаем рабочий скрипт, как раньше.

14.09.2023    18832    human_new    27    

80

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    14734    YA_418728146    7    

166
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. A_Max 20 06.06.19 18:08 Сейчас в теме
Хороший разбор нюансиков.
ivnik; kaliuzhnyi; Deslime; ram8291; Бубузяка; +5 Ответить
2. MikhailDr 07.06.19 07:58 Сейчас в теме
Классная статья, спасибо
3. EliasShy 48 07.06.19 08:58 Сейчас в теме
Интересно было бы по производительности и потреблению памяти на больших объемах
Yashazz; PLAstic; +2 Ответить
4. Dmitryiv 161 07.06.19 09:43 Сейчас в теме
Вместо того, чтобы реализовать в платформе поддержку регулярных выражений занимаются велосипедостроением.
maksa2005; romulanin; user717534; Dmitri93; rpgshnik; Jeka44; kris_barbina; Астиг; A_Max; Yashazz; sashocq; Shmell; zarankony; Поручик; DitriX; +15 Ответить
5. Поручик 4692 07.06.19 11:03 Сейчас в теме
Сам обжёгся как-то. Не посмотрел как следует, потом срочно обновлял конфы на пяти серверах. К счастью, без последствий.
6. DitriX 2101 07.06.19 11:58 Сейчас в теме
тут стоит отметить, что СтрРазделить - работает оптимально при количестве строк не более 1000-2000, если больше - то дешевле вначале разделить их на массивы, а потом уже вызвать разделение как надо и объединять,ибо скорость падает экспоненциально.
Yashazz; for_sale; SeiOkami; +3 Ответить
7. SeiOkami 3515 07.06.19 12:29 Сейчас в теме
(6)
если больше - то дешевле вначале разделить их на массивы

интересно, так не пробовали. Надо будет провести эксперимент и, возможно, доработать обёртку с учётом этого
8. vasilev2015 2722 07.06.19 13:53 Сейчас в теме
Есть очень простой прием, чтобы получить подстроки из строки с разделителями.

Замените разделитель на Символы.ВК (или Символы.ПС - извините, пишу по памяти)

Результат - многострочная строка, к каждой подстроке можно обращаться по номеру, метод СтрПолучитьСтроку.

БСП рулит.
rpgshnik; WellMaster; Yashazz; RomanMartynenko; madonov; Поручик; +6 Ответить
10. SeiOkami 3515 07.06.19 14:59 Сейчас в теме
(8) проблема будет, когда в тексте уже есть этот специальный символ.
for_sale; +1 Ответить
23. madonov 259 10.06.19 08:28 Сейчас в теме
Что мешает использовать не один специальный символ, а их последовательность, которую никогда не встретишь в реальном тексте?

//Меняем перенос строки на редкую последовательность символов, которая никогда не встретится в реальном тексте
НачальнаяСтрока = СтрЗаменить(НачальнаяСтрока, Символы.ПС, "~#!#!#~");

//Меняем строку разделитель на перенос строки
МногоСтрочнаяСтрока = СтрЗаменить(НачальнаяСтрока, Разделитель, Символы.ПС);

//Обходим многострочную строку
Для СчетчикСтрок = 1 По СтрЧислоСтрок(МногоСтрочнаяСтрока) Цикл
	
	Стр = СтрПолучитьСтроку(МногоСтрочнаяСтрока, СчетчикСтрок);
	
	//Меняем последовательность символов обратно на пернос строки
	Стр = СтрЗаменить(Стр , "~#!#!#~", Символы.ПС);
	
	Сообщить(Стр);
	
КонецЦикла;
Показать
user1951539; +1 Ответить
9. uno-c 264 07.06.19 14:57 Сейчас в теме
РазложитьСтрокуВМассивПодстрок() уйдёт в небытие...
Что будет? зациклится?
11. starik-2005 3087 07.06.19 22:07 Сейчас в теме
Массиф = СтрРазделить(СтрЗаменить(ИсходнаяСтрока, Разделитель, "|"), "|")
Это на тему как бороться с неодинаковостью. С пустыми строками все вообще плывет, поэтому или они тебе нужны, или нет - ты должен это сразу понимать. Юзать БСПшный механизм бессмысленно совершенно.
12. SeiOkami 3515 07.06.19 22:21 Сейчас в теме
(11) это не выход. Что будет, если в строке изначально был символ "|" ?
13. starik-2005 3087 07.06.19 23:26 Сейчас в теме
(12)
изначально был симво
Так тыжпрограммист - должен знать, что у тебя в строчке будет, а что - нет. Так у тебя в строчке может и разделитель вдруг потребоваться, а он заменой символов выпилится )))

ЗЫ: но это все фигня. Я как-то давненько на С++ написал прогу для чтения паспортов недействительных (120кк штук). При компиляции без оптимизации они читались минуты полторы на FX8320 (3500MHz), а с оптимизацией - за 16 сек вроде бы. И что-то я забыл про эту прогу. А сегодня скачал компилятор оптимизирующий от АМД, в итоге прогнал вообще без оптимизации на Ryzen 1600 (3200MHz) - 29 сек, т.е. раза этак в два с лишним быстрее 8320-го. Ну, думаю, давай-ка заоптимайзю с -march=native и О3 - в итоге 8 сек. Круть, думаю, давай-ка -flto - 7.5 сек. Ну, думаю, совсем круто - буду собирать постгрес, но решил посмотреть что и в обычном g++-7 - оказалось, что ровно то же. Потом поглядел в пакетах, а там g++-8 уже. Поставил его и на нем со всей этой оптимизацией - в итоге 6.9 сек. А странно то, что у коллеги на i9-9900K медленнее работает, хотя операция однопоточная.

А Вы мне тут про СтрРазделить )))
14. SeiOkami 3515 08.06.19 05:31 Сейчас в теме
(13) ну вот и получается, что это очередной метод с "нюансом", который нужно помнить и обрабатывать. И когда в строке окажется символ "|", нужно будет либо перебирать другие возможные символы для замены и проверять их наличие в строке, либо, в конце концов, просто применить универсальный механизм БСП.
15. starik-2005 3087 08.06.19 12:55 Сейчас в теме
(14) так на то ты и программист. Не нравится палка - замени на решетку, доллар, амперсанд, собаку, какой-нить непечатаемый символ и т.д. Использовать БСП-шный механизм резона нет никакого совершенно.

ЗЫ: из реального мира пример - замена кучи всяких символов, включая ограничители тегов, в XML на "&хххх;". Ну и всяческие извращения при вставке кавычек в строку. Кто-то \" пишет, кто-то "".
16. SeiOkami 3515 08.06.19 12:58 Сейчас в теме
(15) так и как мне поступить, если мне нужно разобрать любой текст разделителем из единой строки?
Пока нет альтернативы, используем БСП. В этом и резон.
17. starik-2005 3087 08.06.19 13:00 Сейчас в теме
(16)
так и как мне поступить, если мне нужно разобрать любой текст
1. Ограничить ввод, т.е. определить правила для входящего потока.
2. Проверять перед разделением на наличие включений решеток и иных символов.
3. Не ставить задачи разобрать любой текст - учитесь у создателей XML и всех его подвидов - они просто запилили стандарт.
19. SeiOkami 3515 08.06.19 13:08 Сейчас в теме
(17)разговор ни о чём. У платформы есть универсальный механизм. У БСП есть универсальный механизм. Каждый применяется в своём время/месте. Если Вам в задаче не нужен универсальный механизм, а нужен свой - применяйте. Но глупо говорить, что универсальный механизм не нужен вовсе. Всему своё место и время.
20. starik-2005 3087 08.06.19 13:10 Сейчас в теме
(19)
Каждый применяется в своём время/месте.
Если Ваш алгоритм плох - да. Если он хорош - достаточно механизмов платформы. Но Вы всегда можете привести конкретный пример (не в общем и целом, а вот очень конкретно с данными), где нужна именно БСП-шная функция.
18. starik-2005 3087 08.06.19 13:06 Сейчас в теме
(16) кстати, вот у Вас там есть какой-то конструктор ВПФ, а в нем я какой-то запросник увидел на картинке. Как Вы анализируете запрос, например, на наличие временных таблиц, подзапросов и прочего? Да, можно юзать схему запроса - там все есть, но с большой конфигурацией она работает долго. Быстрее получается разделить запрос на строки и в цикле проанализировать его, найти в нем все начала строк, комментарии, отсечь их, и уже потом в запросе без строковых констант и комментариев производить анализ. И исходя из задачи при анализе в данном случае совершенно любого текста запроса нам БСП-шная функция понадобится, как Вы думаете?
21. Бубузяка 62 09.06.19 11:53 Сейчас в теме
Достойное исследование. Автору респект. У самого в конфигурации есть костылик ....
Функция РазобратьСтрокуСРазделителями(ИсходнаяСтрока, Разделитель = ",") Экспорт
	
	РезМассив = Новый Массив;
	
	// Разделитель бывает длиной строки > 1, учитывая особенность "СтрЗаменить",
	// заменим его на редкий односимвольный разделитель (смайлик) Символ(9786).
	Сепаратор = Символ(9786);
	Образец   = СтрЗаменить(ИсходнаяСтрока, Разделитель, Сепаратор);
	РезМассив = СтрРазделить(Образец, Сепаратор, Ложь);
		
	Возврат РезМассив;
	
КонецФункции
Показать
user1300729; +1 Ответить
22. for_sale 976 09.06.19 19:27 Сейчас в теме
Да, есть такая гадость.
1С как всегда в своём репертуаре - вместо того, чтобы реализовать нормальную нужную функцию, под её видом реализуют неведомую фигню. Интересно, кто-то когда-то вообще сталкивался с чем-то, что решается вот этой вот стандартной 1Совской хренью? Я даже навскидку придумать не могу, нахрена она вообще нужна.
24. comptr 35 10.06.19 08:35 Сейчас в теме
Было бы здорово, если бы какой-нибудь из методов ещё научился понимать, что текст внутри кавычек не нужно разделять, несмотря на наличие разделителя внутри.
starik-2005; SeiOkami; Perfolenta; +3 Ответить
26. SeiOkami 3515 10.06.19 09:20 Сейчас в теме
(24) очень было бы полезно. Каждый раз приходится изобретать свой дикий велосипед для подобных задач
25. SeiOkami 3515 10.06.19 09:18 Сейчас в теме
Объявляем сбор всех вариантов алгоритма по расщеплению. После этого проведём анализ, соберём "обёртку" со всеми алгоритмами и проведём "нагрузочное" тестирование 🤘
user1300729; +1 Ответить
27. vec435 17 10.06.19 09:52 Сейчас в теме
28. Vlan 36 10.06.19 15:41 Сейчас в теме
Я за РазложитьСтрокуВМассивПодстрок() с ее предсказуемым результатом. Не пользовался встроенной функцией, сам не знаю почему, на интуитивном уровне. Теперь картина прояснилась. Автору спасибо.
29. Yashazz 4790 10.06.19 16:02 Сейчас в теме
Давно собирался раскопать эти нюансы, автору спасибо. Да, платформа "молодец", но и БСП я бы не доверял. Обычно юзаю вариант с Символы.ПС и СтрПолучитьСтроку, а перед этим экранирую исходные ПС, но наиболее люто плюсую мысли о регулярках, которых нет (зато есть видеозвонки, ага ага).
30. for_sale 976 11.06.19 12:09 Сейчас в теме
(29)
(зато есть видеозвонки, ага ага)

Интересно, а видеозвонками и этими чатами их вообще кто-нибудь пользуется? По количеству никому не нужных изобретений 1С скоро сравняется в виндавсом))
EugeneSemyonov; user717534; +2 Ответить
31. dmalyshev 23 13.06.19 10:16 Сейчас в теме
Если вы знаете как работает функция - то и результат можешь предсказать. и не нужно писать аналитическую статью.
Поэтому замена строки разделителя на символ и использование СтрРазложить - интуитивно понятно и просто даже без статьи.
Не нужно искать универсальных функций на все случаи жизни. Вы же программисты. Чего нет - всегда можно самому написать. Как пример - функция РазложитьСтрокуВМассивПодстрок() - посадили разработчики БСП студента Васю, и он написал такую функцию. Чем вы хуже?

.
32. starik-2005 3087 13.06.19 14:12 Сейчас в теме
(31)
посадили разработчики БСП студента Васю, и он написал такую функцию.
Ну может и не студент написал эту функцию. А нужна она была т.к. в платформе раньше "СтрРазделить" не было вообще. А добрым 1С-никам давно пора бы сделать разложение с регулярками, вот тогда заживем! ))) Хотя... Есть у меня на эту тему одна мысль относительно 14-й платформы.
user1300729; +1 Ответить
33. dmalyshev 23 13.06.19 18:31 Сейчас в теме
(32) Согласен что не было. Все же меняется. Будьте гибче.
34. Yashazz 4790 18.06.19 13:44 Сейчас в теме
(32)
Есть у меня на эту тему одна мысль относительно 14-й платформы
Потоками резать?
35. 7OH 70 10.07.20 17:56 Сейчас в теме
а чем разделить правильно такую строку на 4 элемента?
"Вася, ПУпкин", ННН, "1,234.00", 123
EXCEL такое умеет разбирать правильно
36. SeiOkami 3515 10.07.20 18:00 Сейчас в теме
(35) СтрРазделить в несколько заходов.
Для всего сложного есть регулярки
37. 7OH 70 10.07.20 18:04 Сейчас в теме
(36) Были бы они в 1С - было бы волшебно.
DLL не рассматриваю - код должен выполняться на любой платформе.
38. SeiOkami 3515 10.07.20 18:05 Сейчас в теме
(37) ну тогда простым 1С-алгоритмом)
Я бы тоже рад развитию 1С, но что поделаешь. Зато есть Исполнитель 🤣
Оставьте свое сообщение