powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Разбить строку на подстроки определенной длины, не разбивая слова
19 сообщений из 19, страница 1 из 1
Разбить строку на подстроки определенной длины, не разбивая слова
    #39883034
Фотография DimaU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Наверное, классика) Подскажите красивое решение, плиз.
Как разбить произвольную длинную строку (текст) на подстроки определенной длины (например, максимум 70 символов), не при этом разбивая слова (в конце подстрок). То есть подстроки могут быть длиной до(!) 70 символов. Исходный текст - это слова, разделенные пробелами, запятыми...
...
Рейтинг: 0 / 0
Разбить строку на подстроки определенной длины, не разбивая слова
    #39883039
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaU,

поищите код на C#, создайте CLR функцию.
...
Рейтинг: 0 / 0
Разбить строку на подстроки определенной длины, не разбивая слова
    #39883042
Фотография DimaU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав КолосовDimaU,

поищите код на C#, создайте CLR функцию.
Спасибо. Теоретически можно и SQL-функцию написать, возвращающую table с подстроками...
...
Рейтинг: 0 / 0
Разбить строку на подстроки определенной длины, не разбивая слова
    #39883043
msLex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaUВладислав КолосовDimaU,

поищите код на C#, создайте CLR функцию.
Спасибо. Теоретически можно и SQL-функцию написать, возвращающую table с подстроками...
Можно, конечно.
Теоретически, она выглядит не сложно - искать первый пробел слева от символа со смещением от текущего 70, получать нужную подстроку и переводить текущий символ на найденный пробел. Если осталось меньше 70 символов, то выводить весь остаток .
Надо только учесть, что возможны строки, где пробелов не встречается больше 70 символов.


Но префоманс будет не ахти. Работа со строками не самая сильная сторона TSQL
...
Рейтинг: 0 / 0
Разбить строку на подстроки определенной длины, не разбивая слова
    #39883046
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaU,

можете поэкспериментировать, но читаемость такого кода у меня под сомнением.
...
Рейтинг: 0 / 0
Разбить строку на подстроки определенной длины, не разбивая слова
    #39883051
Фотография court
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
не претендуя на "красоту" :)

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
declare @str varchar(max)='Наверное, классика) Подскажите красивое решение, плиз. Как разбить произвольную длинную строку (текст) на подстроки определенной длины (например, максимум 70 символов), не при этом разбивая слова (в конце подстрок). То есть подстроки могут быть длиной до(!) 70 символов. Исходный текст - это слова, разделенные пробелами, запятыми...'
declare @len int = 70
--
;with cte as (
	select 
		rn				=1 
		,pos_delim		=@len - patindex('%[ ,.-]%',reverse(left(@str,@len)))
		,res			=substring(@str, 1, @len-patindex('%[ ,.-]%',reverse(left(@str,@len)))+1)
		,[str]			=right(@str, case when len(@str)-@len+patindex('%[ ,.-]%',reverse(left(@str,@len)))-1>0 then len(@str)-@len+patindex('%[ ,.-]%',reverse(left(@str,@len)))-1 else 0 end)

	union all

	select
		rn				=rn+1
		,pos_delim		=@len - patindex('%[ ,.-]%',reverse(left([str],@len))) 
		,res			=substring([str], 1, @len-patindex('%[ ,.-]%',reverse(left([str],@len)))+1)
		,[str]			=right([str], case when len([str])-@len+patindex('%[ ,.-]%',reverse(left([str],@len)))-1>0 then len([str])-@len+patindex('%[ ,.-]%',reverse(left([str],@len)))-1 else 0 end)
	from cte 
	where len([str]) > 0 
)
select * from cte 


rnres1Наверное, классика) Подскажите красивое решение, плиз. Как разбить 2произвольную длинную строку (текст) на подстроки определенной длины 3(например, максимум 70 символов), не при этом разбивая слова (в конце 4подстрок). То есть подстроки могут быть длиной до(!) 70 символов. 5Исходный текст - это слова, разделенные пробелами, запятыми...
...
Рейтинг: 0 / 0
Разбить строку на подстроки определенной длины, не разбивая слова
    #39883077
andy st
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
court,
(c) не ямы рассмотрели предложение по разработке информационной системы и приняли решение купить небольшую партию той травы, которую Вы курите
...
Рейтинг: 0 / 0
Разбить строку на подстроки определенной длины, не разбивая слова
    #39883090
Фотография defragmentator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Разбить на слова, слова сложить в строки
...
Рейтинг: 0 / 0
Разбить строку на подстроки определенной длины, не разбивая слова
    #39883093
Владислав Колосов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Любой боксовый контрол делает это автоматически.
...
Рейтинг: 0 / 0
Разбить строку на подстроки определенной длины, не разбивая слова
    #39883096
Фотография DimaU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
court, спасибо!
рекурсия - сила!)
Единственное, для вырожденного случая плохо работает) если исходная строка меньше 70 символов...
...
Рейтинг: 0 / 0
Разбить строку на подстроки определенной длины, не разбивая слова
    #39883098
Фотография court
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaUЕдинственное, для вырожденного случая плохо работает) если исходная строка меньше 70 символов...в смысле ?

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
declare @str varchar(max)='Наверное, классика) Подскажите красивое решение, плиз.'
declare @len int = 70
--
;with cte as (
	select 
		rn				=1 
		,pos_delim		=@len - patindex('%[ ,.-]%',reverse(left(@str,@len)))
		,res			=substring(@str, 1, @len-patindex('%[ ,.-]%',reverse(left(@str,@len)))+1)
		,[str]			=right(@str, case when len(@str)-@len+patindex('%[ ,.-]%',reverse(left(@str,@len)))-1>0 then len(@str)-@len+patindex('%[ ,.-]%',reverse(left(@str,@len)))-1 else 0 end)

	union all

	select
		rn				=rn+1
		,pos_delim		=@len - patindex('%[ ,.-]%',reverse(left([str],@len))) 
		,res			=substring([str], 1, @len-patindex('%[ ,.-]%',reverse(left([str],@len)))+1)
		,[str]			=right([str], case when len([str])-@len+patindex('%[ ,.-]%',reverse(left([str],@len)))-1>0 then len([str])-@len+patindex('%[ ,.-]%',reverse(left([str],@len)))-1 else 0 end)
	from cte 
	where len([str]) > 0 
)
select rn, res from cte order by 1


rnres1Наверное, классика) Подскажите красивое решение, плиз.
...
Рейтинг: 0 / 0
Разбить строку на подстроки определенной длины, не разбивая слова
    #39883099
Фотография DimaU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав КолосовЛюбой боксовый контрол делает это автоматически.
Это да)
Просто есть потребность выдать длинный текст в отчет (word-xml) с разрисованным подчеркиваниваем (независимо от текста, то есть простое подчеркивание текста строки-результата не подойдет... из-за переноса слов - концы линий подчеркивания плывут - не выровнены по правому краю). Думаю как реализовать...
...
Рейтинг: 0 / 0
Разбить строку на подстроки определенной длины, не разбивая слова
    #39883105
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
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.
declare @str varchar(max) = 'Наверное, классика) Подскажите красивое решение, плиз. Как разбить произвольную длинную строку (текст) на подстроки определенной длины (например, максимум 70 символов), не при этом разбивая слова (в конце подстрок). То есть подстроки могут быть длиной до(!) 70 символов. Исходный текст - это слова, разделенные пробелами, запятыми...';
declare @len int = 70;

with t as
(
 select
  d.s, d.f
 from
  (select @str) a(s) cross apply
  (select left(a.s, @len)) b(s1) cross apply
  (select patindex('% %', reverse(b.s1))) c(p) cross apply
  (select rtrim(left(a.s, @len - c.p)), substring(a.s, isnull(@len - nullif(c.p, 0) + 2, @len), cast(0x7fffffff as int))) d(f, s)

 union all

 select
  d.s, d.f
 from
  t a cross apply
  (select left(a.s, @len)) b(s1) cross apply
  (select patindex('% %', reverse(b.s1))) c(p) cross apply
  (select rtrim(left(a.s, @len - c.p)), substring(a.s, isnull(@len - nullif(c.p, 0) + 2, @len), cast(0x7fffffff as int))) d(f, s)
 where
  a.s > ''
)
select f, len(f) from t;
...
Рейтинг: 0 / 0
Разбить строку на подстроки определенной длины, не разбивая слова
    #39883122
Фотография DimaU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
courtDimaUЕдинственное, для вырожденного случая плохо работает) если исходная строка меньше 70 символов...в смысле ?

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
declare @str varchar(max)='Наверное, классика) Подскажите красивое решение, плиз.'
declare @len int = 70
--
;with cte as (
	select 
		rn				=1 
		,pos_delim		=@len - patindex('%[ ,.-]%',reverse(left(@str,@len)))
		,res			=substring(@str, 1, @len-patindex('%[ ,.-]%',reverse(left(@str,@len)))+1)
		,[str]			=right(@str, case when len(@str)-@len+patindex('%[ ,.-]%',reverse(left(@str,@len)))-1>0 then len(@str)-@len+patindex('%[ ,.-]%',reverse(left(@str,@len)))-1 else 0 end)

	union all

	select
		rn				=rn+1
		,pos_delim		=@len - patindex('%[ ,.-]%',reverse(left([str],@len))) 
		,res			=substring([str], 1, @len-patindex('%[ ,.-]%',reverse(left([str],@len)))+1)
		,[str]			=right([str], case when len([str])-@len+patindex('%[ ,.-]%',reverse(left([str],@len)))-1>0 then len([str])-@len+patindex('%[ ,.-]%',reverse(left([str],@len)))-1 else 0 end)
	from cte 
	where len([str]) > 0 
)
select rn, res from cte order by 1


rntres1tНаверное, классика) Подскажите красивое решение, плиз.

сорри, это pos_delim странно выходит, если длина строки меньше 70 символов
...
Рейтинг: 0 / 0
Разбить строку на подстроки определенной длины, не разбивая слова
    #39883124
Minamoto
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaUВладислав КолосовЛюбой боксовый контрол делает это автоматически.
Это да)
Просто есть потребность выдать длинный текст в отчет (word-xml) с разрисованным подчеркиваниваем (независимо от текста, то есть простое подчеркивание текста строки-результата не подойдет... из-за переноса слов - концы линий подчеркивания плывут - не выровнены по правому краю). Думаю как реализовать...
Сделать выравнивание по ширине...
Не надо плиз заниматься форматированием на уровне SQL-кода - это дикий костыль.


А сама задача имеет право на жизнь, например, чтобы преодолеть ограничение студии в 65535 символов в результирующих данных, при этом обрезать не посередине слов, а по переносам строки или пробелам. Для отладки делал такое, когда правил хранимки с мега-длинным динамически собранным SQL.
...
Рейтинг: 0 / 0
Разбить строку на подстроки определенной длины, не разбивая слова
    #39883142
invm
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Поправочка
Код: sql
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.
declare @str varchar(max) = 'Наверное, классика) Подскажите красивое решение, плиз. Как разбить произвольную длинную строку (текст) на подстроки определенной длины (например, максимум 70 символов), не при этом разбивая слова (в конце подстрок). То есть подстроки могут быть длиной до(!) 70 символов. Исходный текст - это слова, разделенные пробелами, запятыми...';
declare @len int = 70;

with t as
(
 select
  d.s, d.f
 from
  (select @str) a(s) cross apply
  (select left(a.s, @len)) b(s1) cross apply
  (select patindex('% %', reverse(b.s1))) c(p) cross apply
  (select rtrim(left(a.s, @len - c.p)), substring(a.s, isnull(@len - nullif(c.p, 0) + 2, @len), cast(0x7fffffff as int))) d(f, s)

 union all

 select
  d.s, d.f
 from
  t a cross apply
  (select left(a.s, @len)) b(s1) cross apply
  (select patindex('% %', reverse(b.s1))) c(p) cross apply
  (select rtrim(left(a.s, @len - c.p)), substring(a.s, isnull(@len - nullif(c.p, 0) + 2, @len), cast(0x7fffffff as int))) d(f, s)
 where
  len(a.s) > @len
)
select f, len(f) from t;
...
Рейтинг: 0 / 0
Разбить строку на подстроки определенной длины, не разбивая слова
    #39883166
Alexander Us
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Владислав КолосовDimaU,
поищите код на C#, создайте CLR функцию.
Поддерживаю.


DimaU, Вам придётся чуть повозиться, но оно (SQL.CLR) того стоит.


Код: c#
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.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
  public partial class Utils
    {
        

        [SqlFunction(Name = "fn_Split", DataAccess = DataAccessKind.None, FillRowMethodName = "GetRowData1", IsDeterministic = true)]
        public static IEnumerable fn_Split(String StrToSplit, String Splitter)
        {
            List<TableRow1> ret = new List<TableRow1>();

            if (StrToSplit == null) 
                return ret;         
            
            if (String.IsNullOrEmpty(Splitter)) 
	        {
		        Char[] arr;
                arr = StrToSplit.ToCharArray();
                for (int i = 0; i < arr.Length; i++)
                {
                    ret.Add(new TableRow1(i + 1, arr[i].ToString()));
                }                
	        }
            else 
            {
                String[] arr;
                arr = StrToSplit.Split(new String[] {Splitter}, StringSplitOptions.None);
                for (int i = 0; i < arr.Length; i++)
                {
                    String tmp = arr[i];                    
                    ret.Add(new TableRow1(i+1, tmp));
                }
            }
                  
            return ret;            
        }

        [SqlFunction(Name = "fn_SplitByLen", DataAccess = DataAccessKind.None, FillRowMethodName = "GetRowData1", IsDeterministic = true)]
        public static IEnumerable fn_SplitByLen(String StrToSplit, Int32 Len)
        {
            List<TableRow1> ret = new List<TableRow1>();
            if (StrToSplit == null)
                return ret;

            if (Len <= 0)
                throw new ArgumentException("param len <= 0");

            for (int i = 0; i * Len < StrToSplit.Length; i++)
            {
                String tmp = StrToSplit.Substring(i * Len, Math.Min(Len, StrToSplit.Length - i * Len));
                ret.Add(new TableRow1(i + 1, tmp));
            }

            return ret;                       
        }



       

        //######################
        public static void GetRowData1(object o, out SqlInt32 RowNr, out SqlChars Data)
        {
            TableRow1 row = (TableRow1)o;
            RowNr = new SqlInt32(row.RowNr);
            Data = new SqlChars(row.Value);
        }

        public struct TableRow1
        {
            public int RowNr;
            public string Value;

            public TableRow1(int RowNr, string Value)
            {
                this.RowNr = RowNr;
                this.Value = Value;
            }
        }


 
        }

...
Рейтинг: 0 / 0
Разбить строку на подстроки определенной длины, не разбивая слова
    #39883358
Фотография Tigrist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DimaUНаверное, классика) Подскажите красивое решение, плиз.
Как разбить произвольную длинную строку (текст) на подстроки определенной длины (например, максимум 70 символов), не при этом разбивая слова (в конце подстрок). То есть подстроки могут быть длиной до(!) 70 символов. Исходный текст - это слова, разделенные пробелами, запятыми...

До 70 символов, Карл!

Это значит чуть по сложнее, искать пробел от 70го символа в сторону начала строки а не после
...
Рейтинг: 0 / 0
Разбить строку на подстроки определенной длины, не разбивая слова
    #39883726
Сруль.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как бы я такое делал?
Циклом от 70 позиции с шагом (-1) найти первый пробел,
его номер знаем, вырезаем подстроку с первой позиции до найденной, типа, этого пробела.
И повторяем, пока исходная строка не сойдёт в ноль.
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Разбить строку на подстроки определенной длины, не разбивая слова
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]