BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
SASuserlot
Barite | Level 11

 Thank you for looking for the post.  I am unsure if this can be achievable, but I Want to put it out there to decide whether it is feasible?

My order of preference, If you think at any step it's too much work or not possible or too many conditions involved please ignore that point.

 

1. I want to insert a Character (let's say '@') after every 15 characters. How we can do this?

String: I have a very long string length, I want to insert a character after every 15 characters. If not enough characters at the end then, ignore it.

Want: I have a very @long string len@gth, I want to @insert a charac@ter after ever@y 15 character.@ If not enough @characters at t@he end then, i@gnore it.

 

2. Next, if we reach the end of the string and the characters are less than 15, then we have to ignore it

 

3. Next, if the 15th character becomes the ' Blank space' in the string, then we have to ignore it ( Not sure if this is possible)

Note : in the above 'Want' string "ever@y 15 character.@If ". @ character comes in blank space , is it possible to ignore it? but the next character (@) should be from the blank space.

 

Thank you for your help.

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
AhmedAl_Attar
Ammonite | Level 13

Hi @SASuserlot 

The following should give you a starting point

DATA have(KEEP= string want);
	Length String Want $400 char $1 str $15;
	Array sixteens {1000} $16 _temporary_;

	string = 'I have a very long string length, I want to insert a character after every 15 characters. If not enough characters at the end then, ignore it.';
	/* Set some defaults */
	char='@';
	maxStrLen = 15;
	minStrLen = 14;
	numStrChunk = ceil(length(string)/maxStrLen);
	put numStrChunk=;

	Do i=1 to numStrChunk;
		start=(((i-1) * maxStrLen)+1);
		end=(i * maxStrLen);

		str =substr(string,start,maxStrLen);
		sixteens[i]= ifc((length(str)GE minStrLen),cat(str,char),str);
	end;
	Want= cats(of sixteens(*));
	put want=;
Run;

You might be able to modify it to fit your custom needs

Hope this helps

View solution in original post

24 REPLIES 24
Tom
Super User Tom
Super User

Your pattern is not discernable.

What is the actual goal?  Are you trying to flow text ?

The PUT statement can do that pretty easily.

filename text temp;
data _null_;
  file text lrecl=14 ;
  set have;
  put string;
run;
data _null_;
  infile text;
  input ;
  list;
run;
RULE:     ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0
1         I have a very  14
2         long string le 14
3         ngth, I want t 14
4         o insert a cha 14
5         racter after e 14
6         very 15 charac 14
7         ters. If not e 14
8         nough characte 14
9         rs at the end  14
10        then, ignore i 14
11        t. 2
NOTE: 11 records were read from the infile TEXT.
SASuserlot
Barite | Level 11

Hi Tom, Thanks for your Response. I'm sorry if I am not clear. My goal is to create the string into the Macro variable and use it as a footnote in the RTF, and I have indentation issues ( not regular alignment issues, So I came up with this idea). so I was thinking of inserting the 'white space ' after a specific length. so I need the string after inserting the characters in it.

Reference: this is what I am trying to achieve in my overall goal

https://comp.soft-sys.sas.narkive.com/Lc7LuFXk/getting-indent-in-a-footnote

data str;
x = "I have a very long string length, I want to insert a character after every 15 character. If not enough characters at the end then, ignore it.";
run;

 

 

Tom
Super User Tom
Super User

I would look into whether there is an RTF command you could embed that would tell WORD (or whatever program you use to convert the text of the RTF file into something human readable) would interpret as doing a hanging indent of the text.  Then you don't need to split the string yourself.  And the rendering will be done taking into account any proportional space fonts you might be using.

 

Perhaps some of the codes used in this example: https://support.sas.com/kb/42/377.html

 

SASuserlot
Barite | Level 11

Thanks, @Tom, for directing the resources. I will look and see how I can use it per my needs. For this query @AhmedAl_Attar, the solution work what I asked for. Thank you @AhmedAl_Attar . Not sure I can achieve what I am looking for in the RTFs, but I will keep trying it in different ways.

ballardw
Super User

@SASuserlot wrote:

Hi Tom, Thanks for your Response. I'm sorry if I am not clear. My goal is to create the string into the Macro variable and use it as a footnote in the RTF, and I have indentation issues ( not regular alignment issues, So I came up with this idea). so I was thinking of inserting the 'white space ' after a specific length. so I need the string after inserting the characters in it.

Reference: this is what I am trying to achieve in my overall goal

https://comp.soft-sys.sas.narkive.com/Lc7LuFXk/getting-indent-in-a-footnote

data str;
x = "I have a very long string length, I want to insert a character after every 15 character. If not enough characters at the end then, ignore it.";
run;

 

 


Which specific character to you want to insert. Since you say "macro variable" the specific character can be of concern as the macro processor may interpret your character in some manner.

 

If you are going to build the macro variable in a data step then then you need to define a variable long enough to hold the longest expected text plus the maximum number of inserted characters.

Since you say the destination is RTF you may be able to use the Escapechar and RAW function to insert the specific RTF code string that would indent.

 

Is this code intended to produce something that actually goes into the FOOTNOTE "field" or what ever they call it on each page of a document or just something to place the text once at the end of a table or report section?

SASuserlot
Barite | Level 11

Thank you @ballardw . You guessed it correctly. I am trying to insert the 'White space' or unprintable characters (along with 'escapechar') or other options I am looking at

  1. White space -- ^w^w^w^w^w^w^w^w^w^w
  2.  unprintable character 'a0a0a0a0a0a0'x '
  3. other option-^R/RTF'\ql 

Thank you for reminding me to look over the length of the variable after inserting it. 

I  could not understand what you meant in the last part of your question.  We have a macro that Automatically creates the dataset of the footnotes reading from the xlsx file. and these footnotes convert into footnote variables and will be placed at the end of the  RTF figures or tables.

We have the intermediate codes where it takes care of the splitting the string based on the length or next lines, but we having the indentation  which is a new thing to achieve like example below

our code produce the footnote like this

Abbreviation  a: This is a long string ...................................................... contains'''''''''

solution to find the the problems.

Abbreviation b: This is a long string ...................................................... contains'''''''''

solution to find the the problems.

 

What I am trying to achieve ( Include the the white space or rtf char to indent, we have some thing in code that makes the string goes to next line when there is a word with 'Abbreviation')

Abbreviation a : This is a long string ...................................................... contains'''''''''

                            solution to find the the problems.

Abbreviation b: This is a long string ...................................................... contains'''''''''

                          solution to find the the problems.

 

ballardw
Super User

My question about whether it needs to be a Footnote or not relates to how different programs may treat footnotes.

The word processor programs have areas where they display text at the bottom of the page and if you have a long section of text, tables or images the text is displayed at the bottom of the page until you force a section change or similar.

For some ODS destinations the SAS Footnote can end up in this status. There are other ways to place text into a document than a Footnote statement that might fit your purpose better such as Proc ODSLIST or ODSTEXT. These two procs can use data in a data step and can generate bullet list type items.

You might find the section on Nested Lists in this paper of interest: https://support.sas.com/resources/papers/proceedings20/4526-2020.pdf

 

If the need is to display text after output and not in that special part of the document there might be other choices.

 

Tab characters might align but appearance can change based on document default tab settings. Any other character is going to deal with the vagaries of justified text and varying behavior of different font face and size. Not to mention that some of the ODS features by default ignore leading spaces. There are other ways to place text into a document than a Footnote statement that might fit your purposee

AhmedAl_Attar
Ammonite | Level 13

Hi @SASuserlot 

The following should give you a starting point

DATA have(KEEP= string want);
	Length String Want $400 char $1 str $15;
	Array sixteens {1000} $16 _temporary_;

	string = 'I have a very long string length, I want to insert a character after every 15 characters. If not enough characters at the end then, ignore it.';
	/* Set some defaults */
	char='@';
	maxStrLen = 15;
	minStrLen = 14;
	numStrChunk = ceil(length(string)/maxStrLen);
	put numStrChunk=;

	Do i=1 to numStrChunk;
		start=(((i-1) * maxStrLen)+1);
		end=(i * maxStrLen);

		str =substr(string,start,maxStrLen);
		sixteens[i]= ifc((length(str)GE minStrLen),cat(str,char),str);
	end;
	Want= cats(of sixteens(*));
	put want=;
Run;

You might be able to modify it to fit your custom needs

Hope this helps

SASuserlot
Barite | Level 11

Thank you @AhmedAl_Attar . It worked as per my request Post.  I hope I can make good use of it. Thanks again.

Ksharp
Super User
data str;
x = "I have a very long string length, I want to insert a character after every 15 character. If not enough characters at the end then, ignore it.";

length want $ 400;
want=prxchange('s/(.{15})/\1@/',-1,x);
run;

proc print noobs;run;
SASuserlot
Barite | Level 11

Oh, Wowwwwwwwwwwwww, I didn't see this coming.. one step, everything is done. Thank you. I do have a request. Can you please explain what characters/ options were used in it designated? I got some basic ideas after reading online, but I need more. Can you also refer me to some good references to learn these Pearl Expressions? I read on the SAS page, but the explanation needs to be more detailed. Thank you @Ksharp.

Ksharp
Super User
OK.
/(.{15})/\1@/

dot(.) means any one single character,
{15} means repeat dot(.) exactly 15 times,
that means matching exactly 15 characters.
\1 represent (.{15})
\1@ means replace these 15 characters with these 15 characters and @ . That meet your requirement.

About good "good references to learn these Pearl Expressions"
You could search Pearl Expression at support.sas.com , you could find some good stuff .
SASuserlot
Barite | Level 11

Thank you very much. Can you clarify this

Instead of 1 character, I want to place 'two "@@"' characters after 15 characters.   how will this work? 

data str;
x = "I have a very long string length, I want to insert a character after every 15 character. If not enough characters at the end then, ignore it.";

length want $ 400;
want=prxchange('s/(.{15})/\1@/',-1,x);
run;

  

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 24 replies
  • 3612 views
  • 13 likes
  • 6 in conversation