Как разобрать строку в массив по разделителю?

Для разбора текстовой строки в массив по разделителю (или нескольким разделителям) приведём здесь несколько функций в различных реализациях. Функции получились следующие:

  • Разбор строки в массив по разделителю без учёта пробелов
  • Разбор строки в массив по разделителю с пробелами
  • Разбор строки в массив по нескольким разделителям без учёта пробелов
  • Разбор строки в массив по массиву разделителей с пробелами
  • Разбор строки в массив по сложным разделителям (разделители имеют в своём составе несколько символов).

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

Реализация всех этих функций на языке 1С будет следующая…

1. Функция «Разбор строки в массив по разделителю без учёта пробелов».

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// Разбирает строку в массив подстрок по разделителю. 
// При этом пробелы между подстроками не учитываются.
//
// Параметры:
//	Стр - исходная строка;
//	СтрРазделитель - разделитель, по умолчанию ",";
//	ИгнорироватьПустые - игнорировать ли пустые места между разделителями.
//
// Возвращаемое значение:
//	Массив строк
//
Функция РазобратьСтрокуВМассивПоРазделителю(Знач Стр, СтрРазделитель = ",", ИгнорироватьПустые = Ложь) Экспорт
 
	Результат = Новый Массив;
 
	ВхождениеРазделителя = Найти(Стр, СтрРазделитель);
	Пока ВхождениеРазделителя <> 0 Цикл
		ЧастьДоРазделителя = СокрЛП(Лев(Стр, ВхождениеРазделителя - 1));
		Если НЕ (ИгнорироватьПустые И ПустаяСтрока(ЧастьДоРазделителя)) Тогда
			Результат.Добавить(ЧастьДоРазделителя);
		КонецЕсли;
		Стр = СокрЛП(Сред(Стр, ВхождениеРазделителя + 1));
		ВхождениеРазделителя = Найти(Стр, СтрРазделитель);
	КонецЦикла;
 
	Если НЕ (ИгнорироватьПустые И ПустаяСтрока(Стр)) Тогда
		Результат.Добавить(СокрЛП(Стр));
	КонецЕсли;
 
	Возврат Результат;	
КонецФункции;

2. Функция «Разбор строки в массив по разделителю с пробелами».

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// Разбирает строку в массив подстрок по разделителю. 
// Учитываются пробелы между подстроками и пустые подстроки.
//
// Параметры:
//	Стр - исходная строка;
//	СтрРазделитель - разделитель, по умолчанию ",";
//	ИгнорироватьПустые - игнорировать ли пустые места между разделителями.
//  
// Возвращаемое значение:
//	Массив строк
//
Функция РазобратьСтрокуВМассивПоРазделителюСПробелами(Знач Стр, СтрРазделитель = ",", ИгнорироватьПустые = Ложь) Экспорт
 
	Результат = Новый Массив;
 
	ВхождениеРазделителя = Найти(Стр, СтрРазделитель);
	Пока ВхождениеРазделителя <> 0 Цикл
		ЧастьДоРазделителя = Лев(Стр, ВхождениеРазделителя - 1);
		Если НЕ (ИгнорироватьПустые И ПустаяСтрока(ЧастьДоРазделителя)) Тогда
			Результат.Добавить(ЧастьДоРазделителя);
		КонецЕсли;
		Стр = Сред(Стр, ВхождениеРазделителя + 1);
		ВхождениеРазделителя = Найти(Стр, СтрРазделитель);
	КонецЦикла;
 
	Если НЕ (ИгнорироватьПустые И ПустаяСтрока(Стр)) Тогда
		Результат.Добавить(Стр);
	КонецЕсли;
 
	Возврат Результат;
КонецФункции;

3. Функция «Разбор строки в массив по нескольким разделителям без учёта пробелов».

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// Разбирает строку в массив подстрок по разделителям. 
// При этом пробелы между подстроками не учитываются 
// при условии, что в разделителях тоже нет пробела.
//
// Параметры:
//	Стр - исходная строка;
//	МассивРазделителей - массив используемых разделителей;
//	ИгнорироватьПустые - игнорировать ли пустые места между разделителями.
//
// Возвращаемое значение:
//	Массив строк
//
Функция РазобратьСтрокуВМассивПоРазделителям(Знач Стр, МассивРазделителей, ИгнорироватьПустые = Ложь) Экспорт
 
	Результат = Неопределено;
	Если МассивРазделителей.Количество() > 0 Тогда
		ОсновнойРазделитель = МассивРазделителей[0];
		Для Каждого Разделитель Из МассивРазделителей Цикл
			Стр = СтрЗаменить(Стр, Разделитель, ОсновнойРазделитель);
		КонецЦикла;
 
		Если ОсновнойРазделитель = " " Тогда
			Результат = РазобратьСтрокуВМассивПоРазделителюСПробелами(Стр, ОсновнойРазделитель, ИгнорироватьПустые);
		Иначе
			Результат = РазобратьСтрокуВМассивПоРазделителю(Стр, ОсновнойРазделитель, ИгнорироватьПустые);
		КонецЕсли;
	КонецЕсли;
 
	Возврат Результат;
КонецФункции;

4. Функция «Разбор строки в массив по массиву разделителей с пробелами».

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Разбирает строку в массив подстрок по разделителям. 
// При этом пробелы между подстроками не учитываются.
//
// Параметры:
//	Стр - исходная строка;
//	МассивРазделителей - массив используемых разделителей;
//	ИгнорироватьПустые - игнорировать ли пустые места между разделителями.
//
// Возвращаемое значение:
//	Массив строк
//
Функция РазобратьСтрокуВМассивПоРазделителямСПробелами(Знач Стр, МассивРазделителей, ИгнорироватьПустые = Ложь) Экспорт
 
	Результат = Неопределено;
	Если МассивРазделителей.Количество() > 0 Тогда
		ОсновнойРазделитель = МассивРазделителей[0];
		Для Каждого Разделитель Из МассивРазделителей Цикл
			Стр = СтрЗаменить(Стр, Разделитель, ОсновнойРазделитель);
		КонецЦикла;
		Результат = РазобратьСтрокуВМассивПоРазделителюСПробелами(Стр, ОсновнойРазделитель, ИгнорироватьПустые);
	КонецЕсли;
 
	Возврат Результат;
КонецФункции;

5. Функция «Разбор строки в массив по сложным разделителям».

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// Разбирает строку в массив подстрок по разделителям (в виде строки). 
// При этом пробелы между подстроками не учитываются.
//
// Параметры:
//	Стр - исходная строка;
//	МассивРазделителей - массив используемых разделителей;
//	УчитыватьПробелы - учитывать ли пробелы между разделителями;
//	ИгнорироватьПустые - игнорировать ли пустые места между разделителями.
//
// Возвращаемое значение:
//	Структура строк и разделителей
//
Функция РазобратьСтрокуПоРазделителям(Знач Стр, МассивРазделителей, УчитыватьПробелы = Ложь, ИгнорироватьПустые = Ложь) Экспорт
 
	Результат = Новый Структура;
	ПоследовательностьЗначений = Неопределено;
	ПоследовательностьРазделителей = Неопределено;
 
	Если МассивРазделителей.Количество() > 0 Тогда
		ПоследовательностьЗначений = Новый Массив;
		ПоследовательностьРазделителей = Новый Массив;
 
		Позиция = СтрДлина(Стр);		
		Пока Позиция > 0 Цикл
			//Нахождение минимальной позиции разделителя
			Позиция = 0;
			ТекущийРазделитель = Неопределено; 
			Для Каждого Разделитель Из МассивРазделителей Цикл
				ПозицияРазделителя = Найти(Стр, Разделитель);
				Если ПозицияРазделителя <> 0 И (ПозицияРазделителя < Позиция ИЛИ Позиция = 0) Тогда 
					Позиция = ПозицияРазделителя; 
					ТекущийРазделитель = Разделитель; 
				КонецЕсли; 
			КонецЦикла; 
 
			//Формирование последовательностей
			Если Позиция > 0 Тогда
				Значение = ?(УчитыватьПробелы, Сред(Стр, 1, Позиция-1), СокрЛП(Сред(Стр, 1, Позиция-1)));
				Если НЕ ИгнорироватьПустые ИЛИ НЕ ПустаяСтрока(Значение) Тогда
					ПоследовательностьЗначений.Добавить(Значение);
				КонецЕсли;
				ПоследовательностьРазделителей.Добавить(ТекущийРазделитель);
				Стр = Сред(Стр, Позиция + СтрДлина(ТекущийРазделитель));
			Иначе
				Значение = ?(УчитыватьПробелы, Стр, СокрЛП(Стр));
				Если НЕ ИгнорироватьПустые ИЛИ НЕ ПустаяСтрока(Значение) Тогда
					ПоследовательностьЗначений.Добавить(Значение);
				КонецЕсли;
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
 
	Результат.Вставить("МассивЗначений", ПоследовательностьЗначений);
	Результат.Вставить("МассивРазделителей", ПоследовательностьРазделителей);
 
	Возврат Результат;
КонецФункции;