title: SAS extract substring from string with prxchange or prxpson(prxmatch(prxparse()))
body: <h1>2 SOLUTIONS POSTED AT BOTTOM</h1>
  
  <h2>My code</h2>
  
  <pre><code>    data test;  
          extract_string = "&lt;some string here&gt;";
          my_result1 = prxchange(cat("s/^.*", extract_string, ".*$/$1/"), -1, "A1M_PRE");  
          my_result2 = prxchange(cat("s/^.*", extract_string, ".*$/$1/"), -1, "AC2_0M");  
          my_result3 = prxchange(cat("s/^.*", extract_string, ".*$/$1/"), -1, "GA3_30M");
          my_result4 = prxchange(cat("s/^.*", extract_string, ".*$/$1/"), -1, "DE3_1H30M");  
      run;
  </code></pre>
  
  <h2>Desired results</h2>
  
  <p>Extract the number after <code>_</code> but preceding <code>M</code> in strings that have <code>M</code> at the end. The result set should be:  </p>
  
  <pre><code>    my_result1 = ""  
      my_result2 = "0"  
      my_result3 = "30"  
      my_result4 = "30"
  </code></pre>
  
  <h2>The following <code>extract_string</code> values fail</h2>
  
  <pre><code>"\.*(\d*)M\b\"  
  "\.*(\d*?)M\b\"  
  "\.*(\d{*})M\b\"  
  "\.*(\d{*?})M\b\"  
  "\.*(\d){*}M\b\"  
  "\.*(\d){*?}M\b\"  
  
  "\.*(\d+)M\b\"  
  "\.*(\d+?)M\b\"  
  "\.*(\d{+})M\b\"  
  "\.*(\d{+?})M\b\"  
  "\.*(\d){+}M\b\"  
  "\.*(\d){+?}M\b\"  
  
  "\.*(\d+\d+)M\b\" 
  </code></pre>
  
  <h2>Potential solutions which I would request help with</h2>
  
  <ul>
  <li>Perhaps I just haven't tested the correct <code>extract_string</code> yet. Ideas?</li>
  <li>Perhaps my <code>cat("s/&amp;.*", extract_string, ".*$/$1/")</code> needs to be modified. Ideas?</li>
  <li>Perhaps I need to use <code>prxpson(prxmatch(prxparse()))</code> instead of <code>prxchange</code>. How would that be formulated?</li>
  </ul>
  
  <h2>Links I've looked at but have not been able to successfully implement</h2>
  
  <p><a href="https://support.sas.com/rnd/base/datastep/perl_regexp/regexp-tip-sheet.pdf" rel="nofollow noreferrer">https://support.sas.com/rnd/base/datastep/perl_regexp/regexp-tip-sheet.pdf</a>  </p>
  
  <p><a href="https://www.pharmasug.org/proceedings/2013/CC/PharmaSUG-2013-CC35.pdf" rel="nofollow noreferrer">https://www.pharmasug.org/proceedings/2013/CC/PharmaSUG-2013-CC35.pdf</a>  </p>
  
  <p><a href="https://stackoverflow.com/questions/13862573/sas-prx-to-extract-substring-please">SAS PRX to extract substring please</a>  </p>
  
  <p><a href="https://stackoverflow.com/questions/58275744/extracting-substring-using-regex-in-sas">extracting substring using regex in sas</a>  </p>
  
  <p><a href="https://stackoverflow.com/questions/34667232/extract-substring-from-a-string-in-sas">Extract substring from a string in SAS</a>  </p>
  
  <h1>SOLUTIONS</h1>
  
  <h2>Solution 1</h2>
  
  <p>The suffix in the <code>cat</code> function and the <code>extract_string</code> were modified.</p>
  
  <pre><code>    data test;  
          extract_string = "?(?:_[^_r\n]*?(\d+)M)?$";
          my_result1 = prxchange(cat("s/^.*", extract_string, "/$1/"), -1, "A1M_PRE");
          my_result2 = prxchange(cat("s/^.*", extract_string, "/$1/"), -1, "AC2_0M");
          my_result3 = prxchange(cat("s/^.*", extract_string, "/$1/"), -1, "GA3_30M");
          my_result4 = prxchange(cat("s/^.*", extract_string, "/$1/"), -1, "DE3_1H30M");
      run;
  </code></pre>
  
  <h2>Solution 2</h2>
  
  <p>This solution uses the other <code>prx</code>-family functions: <code>prxparse</code>, <code>prxmatch</code>, and <code>prxposn</code>.</p>
  
  <pre><code>data have;
    length string $10;
    input string;
    datalines;
  A1M_PRE
  AC2_0M
  GA3_30M
  DE3_1H30M
  ;
  
  data want;
    set have;
  
    rxid = prxparse ('/_.*?(\d+)M\s*$/');
  
    length digit_string $8;
  
    if prxmatch (rxid, string) then digit_string = prxposn(rxid,1,string);
  
    number_extracted = input (digit_string, ? 12.);
  run;
  </code></pre>