<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: SAS Function to convert string to Legal SAS Name? in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27375#M5003</link>
    <description>Here is another quick solution if it is acceptable to simply remove all the invalid characters from the string:&lt;BR /&gt;
&lt;BR /&gt;
[pre]&lt;BR /&gt;
95   data _null_;&lt;BR /&gt;
96       string = ' &amp;amp;@ 03 This Is &amp;amp;An. Invalid "SAS" Variable ± Name;';&lt;BR /&gt;
97       ValidName=compress(string, '_', 'adik');&lt;BR /&gt;
98       if anydigit(ValidName) = 1 then validname= substr(ValidName,anyalpha(ValidName));&lt;BR /&gt;
99       put ValidName=;&lt;BR /&gt;
100  run;&lt;BR /&gt;
&lt;BR /&gt;
ValidName=ThisIsAnInvalidSASVariableName&lt;BR /&gt;
[/pre]</description>
    <pubDate>Thu, 04 Nov 2010 09:54:02 GMT</pubDate>
    <dc:creator>polingjw</dc:creator>
    <dc:date>2010-11-04T09:54:02Z</dc:date>
    <item>
      <title>SAS Function to convert string to Legal SAS Name?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27369#M4997</link>
      <description>Suppose I have an arbitrary text string, such as&lt;BR /&gt;
&lt;BR /&gt;
ACD(#)DEF&lt;BR /&gt;
&lt;BR /&gt;
This is not a legal SAS variable name. Is there a function that will convert this to a legal SAS name? &lt;BR /&gt;
&lt;BR /&gt;
I know I can do this with translate function, but then I would need to know every possible illegal character that might appear.</description>
      <pubDate>Wed, 03 Nov 2010 14:04:38 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27369#M4997</guid>
      <dc:creator>Paige</dc:creator>
      <dc:date>2010-11-03T14:04:38Z</dc:date>
    </item>
    <item>
      <title>Re: SAS Function to convert string to Legal SAS Name?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27370#M4998</link>
      <description>I haven't found a function to convert a string to a SAS variable name, but you might have a look at these functions; they might help you get where you need to go.&lt;BR /&gt;
&lt;BR /&gt;
notname function: &lt;A href="http://support.sas.com/documentation/cdl/en/lrdict/63026/HTML/default/viewer.htm#a002197357.htm" target="_blank"&gt;http://support.sas.com/documentation/cdl/en/lrdict/63026/HTML/default/viewer.htm#a002197357.htm&lt;/A&gt;&lt;BR /&gt;
&lt;BR /&gt;
nvalid function: &lt;A href="http://support.sas.com/documentation/cdl/en/lrdict/63026/HTML/default/viewer.htm#a002271952.htm" target="_blank"&gt;http://support.sas.com/documentation/cdl/en/lrdict/63026/HTML/default/viewer.htm#a002271952.htm&lt;/A&gt;</description>
      <pubDate>Wed, 03 Nov 2010 15:02:53 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27370#M4998</guid>
      <dc:creator>Daryl</dc:creator>
      <dc:date>2010-11-03T15:02:53Z</dc:date>
    </item>
    <item>
      <title>Re: SAS Function to convert string to Legal SAS Name?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27371#M4999</link>
      <description>it sounds like a good application for a prxchange()&lt;BR /&gt;
 &lt;BR /&gt;
any prx specialists on-line?</description>
      <pubDate>Wed, 03 Nov 2010 16:23:51 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27371#M4999</guid>
      <dc:creator>Peter_C</dc:creator>
      <dc:date>2010-11-03T16:23:51Z</dc:date>
    </item>
    <item>
      <title>Re: SAS Function to convert string to Legal SAS Name?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27372#M5000</link>
      <description>&amp;gt; I would need to know every possible illegal&lt;BR /&gt;
&amp;gt; character that might appear.&lt;BR /&gt;
&lt;BR /&gt;
Not really. You only need to know what characters are legal. The first character must be alphabetic or an underscore. Subsequent characters can be alphabetic, numeric, or underscores. (See &lt;A href="http://support.sas.com/documentation/cdl/en/lrcon/62955/HTML/default/viewer.htm#a000998953.htm" target="_blank"&gt;Rules for SAS Variable Names&lt;/A&gt;.) Identify legal characters and substitute a legal character (such as '_') for the others.&lt;BR /&gt;
&lt;BR /&gt;
Or perhaps converting these strings to name literals will do the trick for you? Use the VALIDVARNAME=ANY option and change  ABC(#)DEF to 'ABC(#)DEF'n.</description>
      <pubDate>Wed, 03 Nov 2010 17:38:39 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27372#M5000</guid>
      <dc:creator>Tim_SAS</dc:creator>
      <dc:date>2010-11-03T17:38:39Z</dc:date>
    </item>
    <item>
      <title>Re: SAS Function to convert string to Legal SAS Name?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27373#M5001</link>
      <description>&amp;gt; &amp;gt; I would need to know every possible illegal&lt;BR /&gt;
&amp;gt; &amp;gt; character that might appear.&lt;BR /&gt;
&amp;gt; &lt;BR /&gt;
&amp;gt; Not really. You only need to know what characters are&lt;BR /&gt;
&amp;gt; legal. The first character must be alphabetic or an&lt;BR /&gt;
&amp;gt; underscore. Subsequent characters can be alphabetic,&lt;BR /&gt;
&amp;gt; numeric, or underscores. (See&lt;BR /&gt;
&amp;gt; &lt;A href="http://support.sas.com/documentation/cdl/en/lrcon" target="_blank"&gt;Rules&lt;BR /&gt;
&amp;gt; for SAS Variable Names&lt;/A&gt;.) Identify legal&lt;BR /&gt;
&amp;gt; characters and substitute a legal character (such as&lt;BR /&gt;
&amp;gt; '_') for the others.&lt;BR /&gt;
&lt;BR /&gt;
Your solution still requires me to go through the string character by character, and translate as needed. Which is what I was hoping to avoid. Actually, my idea of using TRANSLATE is a whole lot easier for me to program than looping through each character. I was hoping there was a SAS function that would do the job for me.</description>
      <pubDate>Wed, 03 Nov 2010 19:14:48 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27373#M5001</guid>
      <dc:creator>Paige</dc:creator>
      <dc:date>2010-11-03T19:14:48Z</dc:date>
    </item>
    <item>
      <title>Re: SAS Function to convert string to Legal SAS Name?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27374#M5002</link>
      <description>Post=500 &lt;BR /&gt;
&lt;BR /&gt;
I've wondered about this myself.  SAS clearly knows how to do this, with the various IMPORT methods through SAS/ACCESS.&lt;BR /&gt;
&lt;BR /&gt;
&amp;gt; Your solution still requires me to go through the&lt;BR /&gt;
&amp;gt; string character by character, and translate as&lt;BR /&gt;
&amp;gt; needed. &lt;BR /&gt;
&lt;BR /&gt;
You don't actually need to loop every character.  NOTNAME returns character number and when it returns 0 there are no more NOTNAME characters.&lt;BR /&gt;
NVALID will tell you if you need to try at all.&lt;BR /&gt;
&lt;BR /&gt;
This might be a good opportunity to learn PROC FCMP.&lt;BR /&gt;
&lt;BR /&gt;
[pre]&lt;BR /&gt;
1043  data _null_;&lt;BR /&gt;
1044     length name $32;&lt;BR /&gt;
1045     do name = 'ACD(#)DEF','SAS','Hello','1','1C',' ACD(#)DEF  ';&lt;BR /&gt;
1046        if not nvalid(name) then do;&lt;BR /&gt;
1047           notname = notname(trimN(name));&lt;BR /&gt;
1048           do while(notname);&lt;BR /&gt;
1049              substr(name,notname,1)='_';&lt;BR /&gt;
1050              notname = notname(trimN(name));&lt;BR /&gt;
1051              end;&lt;BR /&gt;
1052           if not anyfirst(first(name)) then name = cats('_',name);&lt;BR /&gt;
1053           end;&lt;BR /&gt;
1054        put 'NOTE: ' name=;&lt;BR /&gt;
1055        end;&lt;BR /&gt;
1056     run;&lt;BR /&gt;
&lt;BR /&gt;
NOTE: name=ACD___DEF&lt;BR /&gt;
NOTE: name=SAS&lt;BR /&gt;
NOTE: name=Hello&lt;BR /&gt;
NOTE: name=_1&lt;BR /&gt;
NOTE: name=_1C&lt;BR /&gt;
NOTE: name=_ACD___DEF&lt;BR /&gt;
[/pre]</description>
      <pubDate>Wed, 03 Nov 2010 20:15:08 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27374#M5002</guid>
      <dc:creator>data_null__</dc:creator>
      <dc:date>2010-11-03T20:15:08Z</dc:date>
    </item>
    <item>
      <title>Re: SAS Function to convert string to Legal SAS Name?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27375#M5003</link>
      <description>Here is another quick solution if it is acceptable to simply remove all the invalid characters from the string:&lt;BR /&gt;
&lt;BR /&gt;
[pre]&lt;BR /&gt;
95   data _null_;&lt;BR /&gt;
96       string = ' &amp;amp;@ 03 This Is &amp;amp;An. Invalid "SAS" Variable ± Name;';&lt;BR /&gt;
97       ValidName=compress(string, '_', 'adik');&lt;BR /&gt;
98       if anydigit(ValidName) = 1 then validname= substr(ValidName,anyalpha(ValidName));&lt;BR /&gt;
99       put ValidName=;&lt;BR /&gt;
100  run;&lt;BR /&gt;
&lt;BR /&gt;
ValidName=ThisIsAnInvalidSASVariableName&lt;BR /&gt;
[/pre]</description>
      <pubDate>Thu, 04 Nov 2010 09:54:02 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27375#M5003</guid>
      <dc:creator>polingjw</dc:creator>
      <dc:date>2010-11-04T09:54:02Z</dc:date>
    </item>
    <item>
      <title>Re: SAS Function to convert string to Legal SAS Name?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27376#M5004</link>
      <description>Does the solution need to ensure that distinct strings produce distinct names? For example, should "ABC#DEF" and "ABC!DEF" be converted to two different names?</description>
      <pubDate>Thu, 04 Nov 2010 12:26:56 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27376#M5004</guid>
      <dc:creator>Tim_SAS</dc:creator>
      <dc:date>2010-11-04T12:26:56Z</dc:date>
    </item>
    <item>
      <title>Re: SAS Function to convert string to Legal SAS Name?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27377#M5005</link>
      <description>I would think YES.  Which is a bit complicated than just changing NOTNAME characters.</description>
      <pubDate>Thu, 04 Nov 2010 13:06:22 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27377#M5005</guid>
      <dc:creator>data_null__</dc:creator>
      <dc:date>2010-11-04T13:06:22Z</dc:date>
    </item>
    <item>
      <title>Re: SAS Function to convert string to Legal SAS Name?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27378#M5006</link>
      <description>could push into a hash table</description>
      <pubDate>Thu, 04 Nov 2010 17:07:56 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27378#M5006</guid>
      <dc:creator>Peter_C</dc:creator>
      <dc:date>2010-11-04T17:07:56Z</dc:date>
    </item>
    <item>
      <title>Re: SAS Function to convert string to Legal SAS Name?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27379#M5007</link>
      <description>&amp;gt; Does the solution need to ensure that distinct&lt;BR /&gt;
&amp;gt; strings produce distinct names? For example, should&lt;BR /&gt;
&amp;gt; "ABC#DEF" and "ABC!DEF" be converted to two different&lt;BR /&gt;
&amp;gt; names?&lt;BR /&gt;
&lt;BR /&gt;
For my purposes, the answer is NO, because the incoming strings aren't truly arbitrary. However, I could see situations where the answer would be YES.</description>
      <pubDate>Thu, 04 Nov 2010 18:05:40 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27379#M5007</guid>
      <dc:creator>Paige</dc:creator>
      <dc:date>2010-11-04T18:05:40Z</dc:date>
    </item>
    <item>
      <title>Re: SAS Function to convert string to Legal SAS Name?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27380#M5008</link>
      <description>Instead of using translate to check for every possible illegal character that might appear, as originally proposed, how about using translate to change only the illegal characters that actually do appear?  For example:&lt;BR /&gt;
&lt;BR /&gt;
[pre]&lt;BR /&gt;
37   data _null_;&lt;BR /&gt;
38       length valid_name $ 32;&lt;BR /&gt;
39       string = 'ABC(#)DEF';&lt;BR /&gt;
40      &lt;B&gt; valid_name = translate(string, repeat('_', 50), compress(string,'_', 'adi')); &lt;/B&gt;&lt;BR /&gt;
41       if anydigit(valid_name)=1 then valid_name = '_'!!valid_name;&lt;BR /&gt;
42       put valid_name=;&lt;BR /&gt;
43   run;&lt;BR /&gt;
&lt;BR /&gt;
valid_name=ABC___DEF&lt;BR /&gt;
[/pre]</description>
      <pubDate>Mon, 08 Nov 2010 11:32:57 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/27380#M5008</guid>
      <dc:creator>polingjw</dc:creator>
      <dc:date>2010-11-08T11:32:57Z</dc:date>
    </item>
    <item>
      <title>Re: SAS Function to convert string to Legal SAS Name?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/472877#M121293</link>
      <description>&lt;P&gt;Recently, I met the same problem, here is my solution:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%macro correct_sas_name(name);
%let flag=%sysfunc(notname(&amp;amp;name));
%do %until(&amp;amp;flag=0);
	%let char=%substr(&amp;amp;name,&amp;amp;flag,1);
	%let name=%sysfunc(TRANWRD(&amp;amp;name,&amp;amp;char,_));
	%let flag=%sysfunc(notname(&amp;amp;name));
%end;
h_&amp;amp;name
%mend;

%let test=SAS#123!34;
%let correct_name=%correct_sas_name(&amp;amp;test);

%put &amp;amp;test;
%put &amp;amp;correct_name;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The LOG:&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="LOG.jpg" style="width: 455px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/21368iD567F83C893EEC4C/image-size/large?v=v2&amp;amp;px=999" role="button" title="LOG.jpg" alt="LOG.jpg" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 25 Jun 2018 05:46:58 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/472877#M121293</guid>
      <dc:creator>Slash</dc:creator>
      <dc:date>2018-06-25T05:46:58Z</dc:date>
    </item>
    <item>
      <title>Re: SAS Function to convert string to Legal SAS Name?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/472881#M121294</link>
      <description>&lt;P&gt;Have a look at the function &lt;A href="http://documentation.sas.com/?docsetId=lefunctionsref&amp;amp;docsetTarget=p08pv65zqs289nn1rhylzpn95q71.htm&amp;amp;docsetVersion=9.4&amp;amp;locale=de" target="_self"&gt;nliteral&lt;/A&gt; : Converts a character string that you specify to a SAS name literal.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 25 Jun 2018 07:01:37 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/472881#M121294</guid>
      <dc:creator>andreas_lds</dc:creator>
      <dc:date>2018-06-25T07:01:37Z</dc:date>
    </item>
    <item>
      <title>Re: SAS Function to convert string to Legal SAS Name?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/472926#M121305</link>
      <description>&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/13573"&gt;@Paige&lt;/a&gt;&lt;/P&gt;
&lt;P&gt;Below a RegEx which will replace all illegal characters with an underscore - more or less what some of the SAS import wizards are doing.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data sample;
  have='9ACD(#)D9EF';
  want=prxchange('s/^[^_a-z]|[^\w]/_/oi',-1,strip(have));
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Mon, 25 Jun 2018 11:04:11 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/472926#M121305</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2018-06-25T11:04:11Z</dc:date>
    </item>
    <item>
      <title>Re: SAS Function to convert string to Legal SAS Name?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/473825#M121628</link>
      <description>&lt;P&gt;This is great!&amp;nbsp; I have never used these before, and I just took the time to figure out your string using the SAS help and&amp;nbsp;&lt;A title="RegExr: Learn, Build, &amp;amp; Test RegEx" href="https://regexr.com/" target="_blank"&gt;regexr.com&lt;/A&gt;.&amp;nbsp; One thing I haven't figured out is what the final /oi means.&amp;nbsp; SAS Help only defines the s/&amp;lt;string&amp;gt;/&amp;lt;string&amp;gt;/ part.&amp;nbsp; From trial and error, I believe the i means that it's case insensitive.&amp;nbsp; When I removed the i, the matching on the first&amp;nbsp;character of the string only occured when the first character was a lower case a-z, whereas with the i it matched either lower or upper case.&amp;nbsp; What does the o do?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Second question: \w appears to include more than just A-Z, a-z, 0-9, and _.&amp;nbsp; I used your code on the string "Côte d'Ivoire", and SAS returned "Côte_d_Ivoire".&amp;nbsp; Unfortunately, ô is not permissible in a SAS name.&amp;nbsp; Is there a way to get the perl expression to&amp;nbsp;&lt;EM&gt;only&lt;/EM&gt; check regular letters without diacritical marks?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Thanks!!&lt;/P&gt;</description>
      <pubDate>Wed, 27 Jun 2018 17:04:29 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/473825#M121628</guid>
      <dc:creator>Kastchei</dc:creator>
      <dc:date>2018-06-27T17:04:29Z</dc:date>
    </item>
    <item>
      <title>Re: SAS Function to convert string to Legal SAS Name?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/474067#M121751</link>
      <description>&lt;P&gt;This is good way, thanks.&lt;/P&gt;
&lt;P&gt;But, normally this&amp;nbsp;way is not that common.&lt;/P&gt;</description>
      <pubDate>Thu, 28 Jun 2018 13:32:44 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/474067#M121751</guid>
      <dc:creator>Slash</dc:creator>
      <dc:date>2018-06-28T13:32:44Z</dc:date>
    </item>
    <item>
      <title>Re: SAS Function to convert string to Legal SAS Name?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/474102#M121763</link>
      <description>&lt;P&gt;I think I figured this out.&amp;nbsp; Just posting the answer for others.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The /o apparently&amp;nbsp;just like the o option in the SAS function compress.&amp;nbsp; If you have something complicated in your arguments, the system will figure out that complication only once, rather than each time.&amp;nbsp; It's good if you know the resolved argument isn't going to change.&amp;nbsp; However, upon reading, people generally say that one should never use /o anymore in Perl, because it automatically does this kind of check itself and /o can introduce other logic issues.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Regarding \w, this matches any letter at all that is deemed a valid letter by your language selection.&amp;nbsp; ô is a valid letter on my computer, as are é, ß, õ, ü, î, etc.&amp;nbsp; So \w will select any of these, and not \w will select none of these.&amp;nbsp; I had to use [_A-Za-z0-9] without the /i option or [_a-z0-9] with the /i option in order to truly select valid SAS name characters.&amp;nbsp; For the formula suggested, it required the 'not' version so it became [^_a-z0-9] with the /i option.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Lastly, prxChange is very slow.&amp;nbsp; I figured it would be faster than SAS statements, but after running tests on various size datasets (1 million - 100 million records), SAS statements seem 3-5x faster.&amp;nbsp; Even when requiring multiple statements, SAS was still quicker than prxChange.&amp;nbsp; I was quite surprised.&amp;nbsp; Here are some times I measured from the log.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;                 Time of simple substitution (s)            Time of substitution to valid SAS name (s)&lt;BR /&gt;              Using prxChange  Using SAS statements           Using prxChange  Using SAS statements&lt;BR /&gt;  1M records     4.83    4.73       1.46    1.28                 5.01    4.90       0.99    0.97
  5M records    22.50   25.15       7.63    7.47
 10M records    46.42   48.07      15.78   14.24
 15M records    68.60   72.20      23.13   24.49
 25M records   114.34  120.24      41.45   37.58
 50M records   246.17  245.42      77.19   75.68
 75M records   392.11  360.53     123.49  118.56
100M records   516.63  472.15     156.91  151.37  143.99       512.24             113.03  108.49  147.51

&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;* Set up datasets of various sizes with random strings. *;
data test100 test075 test050 test025 test015 test010 test005 test001;
	length i j length 8. string $ 32. _1-_32 $ 1.;
	array __ {*} _1-_32;

	do i = 1 to 100000000;
		length = floor(32*rand('uniform')) + 1;
		
		do j = 1 to 32;
			if j &amp;lt;= length
				then __[j] = byte(floor(256*rand('uniform')));
				else __[j] = '';
		end;

		string = cat(of __{*});

		                       output test100;
		if i &amp;lt;= 75000000  then output test075;
		if i &amp;lt;= 50000000  then output test050;
		if i &amp;lt;= 25000000  then output test025;
		if i &amp;lt;= 15000000  then output test015;
		if i &amp;lt;= 10000000  then output test010;
		if i &amp;lt;=  5000000  then output test005;
		if i &amp;lt;=  1000000  then output test001;
	end;

	drop i j _:;
run;

* Test replacing without restriction on the first character not being a digit. *;
%macro repeat;
	%do i = 1 %to 17;
		data test001PRX;  set test001;  length valid $ 32.;  valid = prxchange('s/[^_A-Z0-9]/_/i',-1,strip(string));  run;
		data test005PRX;  set test005;  length valid $ 32.;  valid = prxchange('s/[^_A-Z0-9]/_/i',-1,strip(string));  run;
		data test010PRX;  set test010;  length valid $ 32.;  valid = prxchange('s/[^_A-Z0-9]/_/i',-1,strip(string));  run;
		data test015PRX;  set test015;  length valid $ 32.;  valid = prxchange('s/[^_A-Z0-9]/_/i',-1,strip(string));  run;
		data test025PRX;  set test025;  length valid $ 32.;  valid = prxchange('s/[^_A-Z0-9]/_/i',-1,strip(string));  run;
		data test050PRX;  set test050;  length valid $ 32.;  valid = prxchange('s/[^_A-Z0-9]/_/i',-1,strip(string));  run;
		data test075PRX;  set test075;  length valid $ 32.;  valid = prxchange('s/[^_A-Z0-9]/_/i',-1,strip(string));  run;
		data test100PRX;  set test100;  length valid $ 32.;  valid = prxchange('s/[^_A-Z0-9]/_/i',-1,strip(string));  run;

		data test001TRN;  set test001;  length valid $ 32.;  valid = translate(strip(string), repeat('_', length(strip(string))), compress(strip(string),'_abcdefghijklmnopqrstuvwxyz', 'di'));  run;
		data test005TRN;  set test005;  length valid $ 32.;  valid = translate(strip(string), repeat('_', length(strip(string))), compress(strip(string),'_abcdefghijklmnopqrstuvwxyz', 'di'));  run;
		data test010TRN;  set test010;  length valid $ 32.;  valid = translate(strip(string), repeat('_', length(strip(string))), compress(strip(string),'_abcdefghijklmnopqrstuvwxyz', 'di'));  run;
		data test015TRN;  set test015;  length valid $ 32.;  valid = translate(strip(string), repeat('_', length(strip(string))), compress(strip(string),'_abcdefghijklmnopqrstuvwxyz', 'di'));  run;
		data test025TRN;  set test025;  length valid $ 32.;  valid = translate(strip(string), repeat('_', length(strip(string))), compress(strip(string),'_abcdefghijklmnopqrstuvwxyz', 'di'));  run;
		data test050TRN;  set test050;  length valid $ 32.;  valid = translate(strip(string), repeat('_', length(strip(string))), compress(strip(string),'_abcdefghijklmnopqrstuvwxyz', 'di'));  run;
		data test075TRN;  set test075;  length valid $ 32.;  valid = translate(strip(string), repeat('_', length(strip(string))), compress(strip(string),'_abcdefghijklmnopqrstuvwxyz', 'di'));  run;
		data test100TRN;  set test100;  length valid $ 32.;  valid = translate(strip(string), repeat('_', length(strip(string))), compress(strip(string),'_abcdefghijklmnopqrstuvwxyz', 'di'));  run;
	%end;
%mend repeat;

%repeat;

proc compare base = test100TRN compare = test100PRX listAll;  run;
	
* Test again with condition of making first character an underscore if a digit too. *;
%macro repeat2;
	%do i = 1 %to 17;
		data test001PRX;  set test001;  length valid $ 32.;  valid = prxchange('s/^[^_A-Z]|[^_A-Z0-9]/_/i',-1,strip(string));  run;
		data test005PRX;  set test005;  length valid $ 32.;  valid = prxchange('s/^[^_A-Z]|[^_A-Z0-9]/_/i',-1,strip(string));  run;
		data test010PRX;  set test010;  length valid $ 32.;  valid = prxchange('s/^[^_A-Z]|[^_A-Z0-9]/_/i',-1,strip(string));  run;
		data test015PRX;  set test015;  length valid $ 32.;  valid = prxchange('s/^[^_A-Z]|[^_A-Z0-9]/_/i',-1,strip(string));  run;
		data test025PRX;  set test025;  length valid $ 32.;  valid = prxchange('s/^[^_A-Z]|[^_A-Z0-9]/_/i',-1,strip(string));  run;
		data test050PRX;  set test050;  length valid $ 32.;  valid = prxchange('s/^[^_A-Z]|[^_A-Z0-9]/_/i',-1,strip(string));  run;
		data test075PRX;  set test075;  length valid $ 32.;  valid = prxchange('s/^[^_A-Z]|[^_A-Z0-9]/_/i',-1,strip(string));  run;
		data test100PRX;  set test100;  length valid $ 32.;  valid = prxchange('s/^[^_A-Z]|[^_A-Z0-9]/_/i',-1,strip(string));  run;

		data test001TRN;  set test001;  length valid $ 32.;  valid = translate(strip(string), repeat('_', length(strip(string))), compress(strip(string),'_abcdefghijklmnopqrstuvwxyz', 'di'));  if anyDigit(substr(valid, 1, 1))  then substr(valid, 1, 1) = '_';  run;
		data test005TRN;  set test005;  length valid $ 32.;  valid = translate(strip(string), repeat('_', length(strip(string))), compress(strip(string),'_abcdefghijklmnopqrstuvwxyz', 'di'));  if anyDigit(substr(valid, 1, 1))  then substr(valid, 1, 1) = '_';  run;
		data test010TRN;  set test010;  length valid $ 32.;  valid = translate(strip(string), repeat('_', length(strip(string))), compress(strip(string),'_abcdefghijklmnopqrstuvwxyz', 'di'));  if anyDigit(substr(valid, 1, 1))  then substr(valid, 1, 1) = '_';  run;
		data test015TRN;  set test015;  length valid $ 32.;  valid = translate(strip(string), repeat('_', length(strip(string))), compress(strip(string),'_abcdefghijklmnopqrstuvwxyz', 'di'));  if anyDigit(substr(valid, 1, 1))  then substr(valid, 1, 1) = '_';  run;
		data test025TRN;  set test025;  length valid $ 32.;  valid = translate(strip(string), repeat('_', length(strip(string))), compress(strip(string),'_abcdefghijklmnopqrstuvwxyz', 'di'));  if anyDigit(substr(valid, 1, 1))  then substr(valid, 1, 1) = '_';  run;
		data test050TRN;  set test050;  length valid $ 32.;  valid = translate(strip(string), repeat('_', length(strip(string))), compress(strip(string),'_abcdefghijklmnopqrstuvwxyz', 'di'));  if anyDigit(substr(valid, 1, 1))  then substr(valid, 1, 1) = '_';  run;
		data test075TRN;  set test075;  length valid $ 32.;  valid = translate(strip(string), repeat('_', length(strip(string))), compress(strip(string),'_abcdefghijklmnopqrstuvwxyz', 'di'));  if anyDigit(substr(valid, 1, 1))  then substr(valid, 1, 1) = '_';  run;
		data test100TRN;  set test100;  length valid $ 32.;  valid = translate(strip(string), repeat('_', length(strip(string))), compress(strip(string),'_abcdefghijklmnopqrstuvwxyz', 'di'));  if anyDigit(substr(valid, 1, 1))  then substr(valid, 1, 1) = '_';  run;
	%end;
%mend repeat2;

%repeat2;

proc compare base = test100TRN compare = test100PRX listAll;  run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 28 Jun 2018 14:59:40 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/474102#M121763</guid>
      <dc:creator>Kastchei</dc:creator>
      <dc:date>2018-06-28T14:59:40Z</dc:date>
    </item>
    <item>
      <title>Re: SAS Function to convert string to Legal SAS Name?</title>
      <link>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/474268#M121827</link>
      <description>&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/16557"&gt;@Kastchei&lt;/a&gt;&lt;/P&gt;
&lt;P&gt;Thanks for all the testing and debugging.&lt;/P&gt;
&lt;P&gt;As you already figured out:&lt;/P&gt;
&lt;P&gt;o&amp;nbsp; compile once&lt;/P&gt;
&lt;P&gt;I &amp;nbsp; case insensitive&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;As I understand it the o wouldn't be necessary when using a constant string. It's only of importance if you pass in the RegEx via a variable.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;RegEx are resource intensive and though "slow". But they are really powerful when it comes to pattern matching.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;As for the \w: Good catch!&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Here some docu links. Especially the 2nd one (metacharacters) is sometimes a bit hard to find.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://documentation.sas.com/?docsetId=lefunctionsref&amp;amp;docsetTarget=n0r8h2fa8djqf1n1cnenrvm573br.htm&amp;amp;docsetVersion=9.4&amp;amp;locale=en&amp;nbsp;" target="_blank"&gt;http://documentation.sas.com/?docsetId=lefunctionsref&amp;amp;docsetTarget=n0r8h2fa8djqf1n1cnenrvm573br.htm&amp;amp;docsetVersion=9.4&amp;amp;locale=en&amp;nbsp;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://support.sas.com/documentation/cdl/en/lefunctionsref/63354/HTML/default/viewer.htm#p0s9ilagexmjl8n1u7e1t1jfnzlk.htm&amp;nbsp;" target="_blank"&gt;http://support.sas.com/documentation/cdl/en/lefunctionsref/63354/HTML/default/viewer.htm#p0s9ilagexmjl8n1u7e1t1jfnzlk.htm&amp;nbsp;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Cheers,&lt;/P&gt;
&lt;P&gt;Patrick&lt;/P&gt;</description>
      <pubDate>Thu, 28 Jun 2018 21:32:35 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/SAS-Function-to-convert-string-to-Legal-SAS-Name/m-p/474268#M121827</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2018-06-28T21:32:35Z</dc:date>
    </item>
  </channel>
</rss>

