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

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

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

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


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

можете поэкспериментировать, но читаемость такого кода у меня под сомнением.
...
Рейтинг: 0 / 0
30.10.2019, 12:27
    #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
30.10.2019, 13:27
    #39883077
andy st
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбить строку на подстроки определенной длины, не разбивая слова
court,
(c) не ямы рассмотрели предложение по разработке информационной системы и приняли решение купить небольшую партию той травы, которую Вы курите
...
Рейтинг: 0 / 0
30.10.2019, 13:45
    #39883090
defragmentator
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбить строку на подстроки определенной длины, не разбивая слова
Разбить на слова, слова сложить в строки
...
Рейтинг: 0 / 0
30.10.2019, 13:48
    #39883093
Владислав Колосов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбить строку на подстроки определенной длины, не разбивая слова
Любой боксовый контрол делает это автоматически.
...
Рейтинг: 0 / 0
30.10.2019, 13:52
    #39883096
DimaU
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбить строку на подстроки определенной длины, не разбивая слова
court, спасибо!
рекурсия - сила!)
Единственное, для вырожденного случая плохо работает) если исходная строка меньше 70 символов...
...
Рейтинг: 0 / 0
30.10.2019, 14:02
    #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
30.10.2019, 14:03
    #39883099
DimaU
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбить строку на подстроки определенной длины, не разбивая слова
Владислав КолосовЛюбой боксовый контрол делает это автоматически.
Это да)
Просто есть потребность выдать длинный текст в отчет (word-xml) с разрисованным подчеркиваниваем (независимо от текста, то есть простое подчеркивание текста строки-результата не подойдет... из-за переноса слов - концы линий подчеркивания плывут - не выровнены по правому краю). Думаю как реализовать...
...
Рейтинг: 0 / 0
30.10.2019, 14:17
    #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
30.10.2019, 14:52
    #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
30.10.2019, 14:53
    #39883124
Minamoto
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбить строку на подстроки определенной длины, не разбивая слова
DimaUВладислав КолосовЛюбой боксовый контрол делает это автоматически.
Это да)
Просто есть потребность выдать длинный текст в отчет (word-xml) с разрисованным подчеркиваниваем (независимо от текста, то есть простое подчеркивание текста строки-результата не подойдет... из-за переноса слов - концы линий подчеркивания плывут - не выровнены по правому краю). Думаю как реализовать...
Сделать выравнивание по ширине...
Не надо плиз заниматься форматированием на уровне SQL-кода - это дикий костыль.


А сама задача имеет право на жизнь, например, чтобы преодолеть ограничение студии в 65535 символов в результирующих данных, при этом обрезать не посередине слов, а по переносам строки или пробелам. Для отладки делал такое, когда правил хранимки с мега-длинным динамически собранным SQL.
...
Рейтинг: 0 / 0
30.10.2019, 15:23
    #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
30.10.2019, 16:15
    #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
30.10.2019, 22:19
    #39883358
Tigrist
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Разбить строку на подстроки определенной длины, не разбивая слова
DimaUНаверное, классика) Подскажите красивое решение, плиз.
Как разбить произвольную длинную строку (текст) на подстроки определенной длины (например, максимум 70 символов), не при этом разбивая слова (в конце подстрок). То есть подстроки могут быть длиной до(!) 70 символов. Исходный текст - это слова, разделенные пробелами, запятыми...

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

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


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