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

Hi friends,

 

I have one line of code like this:

 

call execute('if cbsa_title ="'||trim(strip(cbsa_title))||'" then IND_COAST = '||strip(ind_coast)||' ;');

 

but when SAS runs this code, it shows:

+ if cbsa_title ="PITTSBURGH PA PMSA   " then IND_COAST = 0 ;

 

As you can see, the strip function in call execute doesn't work as it still contains trailing blanks.

 

I tried many times even adding another trim function and still doesn't work,

Anyone has any idea? Greatly appreciate it!!!!

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

Those are not spaces then.  They are some other invisible character.  Use the $HEX. format to see what they are.  

if cbsa_title =: 'PITTSBURGH' then put cbsa_title $hex. ;

The most commn invisible characters are '09'x (TAB) , '0A'x (LINE FEED) , '0D'x (CARRIAGE RETURN) and 'A0'x (NON BREAKING SPACE).

 

If you do find that your values contain some invisible characters you need to figure how why and what is the right fix.  Do the values being compared by the generated code also include those characters? 

If not then try replacing them with spaces:

cbsa_title = translate(cbsa_title,'    ','090A0DA0'x);

 

Why are you removing the leading spaces?  If you ran the generated code against the same data as used to generate it then it would not match since, unlike trailing spaces, leading spaces are significant in comparisons.

 

Note that removing the trailing spaces will not have any effect on the comparison being generated, it just makes the generated code shorter

These two tests will generate the same answer since SAS ignores the trailing spaces when comparing strings.

cbsa_title ="PITTSBURGH PA PMSA   "
cbsa_title ="PITTSBURGH PA PMSA"

 

Try  using something like this.

call execute(catx(' ','if cbsa_title=',quote(trim(cbsa_title)),'then IND_COAST=',ind_coast,';'));

 

View solution in original post

16 REPLIES 16
ballardw
Super User

Try removing the TRIM function and see what you get.

 

Sometimes it is easier to control results of these multiple concatenations by creating a variable to hold a long string value and then use the variable as the argument for Call Execute.

Julie99999
Obsidian | Level 7
removing trim is the same. I initially only put strip. Thanks anyway.
Tom
Super User Tom
Super User

Those are not spaces then.  They are some other invisible character.  Use the $HEX. format to see what they are.  

if cbsa_title =: 'PITTSBURGH' then put cbsa_title $hex. ;

The most commn invisible characters are '09'x (TAB) , '0A'x (LINE FEED) , '0D'x (CARRIAGE RETURN) and 'A0'x (NON BREAKING SPACE).

 

If you do find that your values contain some invisible characters you need to figure how why and what is the right fix.  Do the values being compared by the generated code also include those characters? 

If not then try replacing them with spaces:

cbsa_title = translate(cbsa_title,'    ','090A0DA0'x);

 

Why are you removing the leading spaces?  If you ran the generated code against the same data as used to generate it then it would not match since, unlike trailing spaces, leading spaces are significant in comparisons.

 

Note that removing the trailing spaces will not have any effect on the comparison being generated, it just makes the generated code shorter

These two tests will generate the same answer since SAS ignores the trailing spaces when comparing strings.

cbsa_title ="PITTSBURGH PA PMSA   "
cbsa_title ="PITTSBURGH PA PMSA"

 

Try  using something like this.

call execute(catx(' ','if cbsa_title=',quote(trim(cbsa_title)),'then IND_COAST=',ind_coast,';'));

 

Julie99999
Obsidian | Level 7

thank you so much. I didn't know about invisible character before. I think like what you said, they're not space. I searched whole afternoon online trying to learn more about this special character.
I guess in my case, the special character is generated in data creation input step. I tried the code
cbsa_title = translate(cbsa_title,' ','090A0DA0'x);
you've listed. It didn't work in my case. Is it likely due to the fact that special characters in my case is not in '090A0DA0'x format?
These stuff are very new to me, I'm trying to digest.
I searched translate function online, didn't find much about what I can put in the third argument
https://support.sas.com/documentation/cdl/en/lefunctionsref/63354/HTML/default/viewer.htm#p05ww22zp7...
Thank you very much

Julie99999
Obsidian | Level 7
the output for "put cbsa_title $hex. ;" is as follows:
42455448455344412D524F434B56494C4C452D46524544455249434B2C204D44092020202020202020202020202020202020
I believe it's '09'x (TAB)
Tom
Super User Tom
Super User

That is definitely a TAB character.

1    filename example temp;
2    data _null_;
3      file example;
4      put '42455448455344412D524F434B56494C4C452D46524544455249434B2C204D4409'x ;
5    run;

NOTE: The file EXAMPLE is:
      Filename=...\#LN00009,
      RECFM=V,LRECL=32767,File Size (bytes)=0,
      Last Modified=15Aug2022:19:20:51,
      Create Time=15Aug2022:19:20:51

NOTE: 1 record was written to the file EXAMPLE.
      The minimum record length was 33.
      The maximum record length was 33.
NOTE: DATA statement used (Total process time):
      real time           0.03 seconds
      cpu time            0.01 seconds


6    data _null_;
7     infile example;
8     input;
9     list;
10   run;

NOTE: The infile EXAMPLE is:
      Filename=...\#LN00009,
      RECFM=V,LRECL=32767,File Size (bytes)=35,
      Last Modified=15Aug2022:19:20:51,
      Create Time=15Aug2022:19:20:51

RULE:     ----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0

1   CHAR  BETHESDA-ROCKVILLE-FREDERICK, MD. 33
    ZONE  445445442544454444245444544422440
    NUMR  25485341D2F3B69CC5D62545293BC0D49
NOTE: 1 record was read from the infile EXAMPLE.
      The minimum record length was 33.
      The maximum record length was 33.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

So converting the TAB to space should have made the generated code not have extra "spaces" before the closing quote.

 

But also note that there are hyphens instead of the spaces you posted before between the words.  Hyphens are another character that might not be what the look like.  Some strings that look like the have hyphens might actual have en-dash or em-dash characters instead.

Patrick
Opal | Level 21

You could use a regular expression that translates all invisible characters to blanks.

call execute('if cbsa_title ="'||trim(strip(cbsa_title))||'" then IND_COAST = '||strip(prxchange('s/\s/ /o',-1,strip(ind_coast)))||' ;');
Julie99999
Obsidian | Level 7
thanks, I think using regular expression really solves the problem in one line of code. Can you please kindly help me understand what does this line of code work? prxchange('s/\s/ /o',-1,strip(ind_coast)))
I googled it but didn't help
Julie99999
Obsidian | Level 7
I understand \s means "Matches any white-space character." but what does s/ and /o mean?
In the regular expression you wrote, 's/\s/ /o', I get \s, but not s/ and / /o.
Any input is appreciated greatly
Tom
Super User Tom
Super User

@Julie99999 wrote:
I understand \s means "Matches any white-space character." but what does s/ and /o mean?
In the regular expression you wrote, 's/\s/ /o', I get \s, but not s/ and / /o.
Any input is appreciated greatly

The general pattern for search and replace is 

s/search string/replacement string/modifiers

So in this case the search string is just the special symbol \s.  The replacement string is just a single space character. 

 

I think the o modifier means repeat until no more matches are found, but I can no longer find any documentation on that.

Normally what you see there instead is the i modifier which means to ignore the case of the letters when matching the search string (pattern).

 

Julie99999
Obsidian | Level 7
Thank you so much, it helps hugely. I searched everywhere but couldn't find the answer. Your response is really helpful, I now understand that Perl regular expression
FreelanceReinh
Jade | Level 19

According to section Compiling a Perl Regular Expression in the PRXCHANGE documentation the /o option ("compile once") is redundant here because the Perl regular expression is a constant (i.e., does not contain a variable).

Julie99999
Obsidian | Level 7
thank you so much, the documentation you attached is really helpful. I learned a lot from it.
yabwon
Onyx | Level 15

An alternative to:

cbsa_title = translate(cbsa_title,'    ','090A0DA0'x);

could be

cbsa_title = compress(cbsa_title, ,"S");

Doc: https://documentation.sas.com/doc/en/pgmsascdc/v_030/lefunctionsref/n0fcshr0ir3h73n1b845c4aq58hz.htm

Bart

 

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 16 replies
  • 1166 views
  • 7 likes
  • 7 in conversation