• PHP Help PHP Coding
  • [RESOLVED] preg_replace insert hyphen -- ABC123 -> ABC-123, A1 -> A-1, etc.

I'm up against a brick wall on this one ... coming into work with the top down seems to have addled my already troubled mind 😉

My "in string" is of this format:

$std_regex1="%[\w]{1,3}\d{1,5}%";   //A1, ABC12345

I want to separate the alpha character(s) from the numerics with a hyphen - the desired "out string" is "A-1" in the first example case, and "ABC-12345" in the second.

So far, I've drawn a blank on this with preg_replace() and was actually considering looping through the entire string to prepend a hyphen to the first instance of a numeric character, but I'm already way too expensive to scale this. 🙁

A good 1/2 hour of searching here and the big G isn't helping, either. Maybe more breakfast/coffee? 😃

Any pointers are appreciated ... I'm sure I'm just being thick as usual.

    Give this a try:

    $array = array('A1','ABC12345');
    foreach( $array as $k => $v ) {
       $array[k] = preg_replace('/(\w{1,3})(\d{1,5})/','\1-\2',$v);
    }
    var_dump($array);
    

      Thanks! It's close, but different test cases fail. Did I not give adequate test cases? The regex will also match things like ab2345, yz33, etc.

      [574] Wed 24.Oct.2012 11:28:43 [kevin@rootbsd][~] cat foo; php foo; cat bar; php bar
      <?php
      $array = array('AB2345','yz33');
      foreach( $array as $k => $v ) {
         $array[$k] = preg_replace('/(\w{1,3})(\d{1,5})/','\1-\2',$v);
      }
      
      var_dump($array);
      array(2) {
        [0]=>
        string(7) "AB2-345"
        [1]=>
        string(5) "yz3-3"
      }
      
      <?php
      $array = array('a1','abc123');
      foreach( $array as $k => $v ) {
         $array[$k] = preg_replace('/(\w{1,3})(\d{1,5})/','\1-\2',$v);
      }
      var_dump($array);
      array(2) {
        [0]=>
        string(3) "a-1"
        [1]=>
        string(7) "abc-123"
      }
      
      

      If it could get the hyphen one character sooner in the other cases it looks golden ... though I need to throw a few thousand test cases at it to be certain. 😃

        Well, then do this instead:

        <?php
        
        $array = array('A1','ABC12345','AB2345','yz33');
        foreach( $array as $k => $v ) {
           $array[$k] = preg_replace('/([a-z]{1,3})(\d{1,5})/i','\1-\2',$v);
        }
        var_dump($array);

        Output:

        >php test2.php
        array(4) {
          [0]=>
          string(3) "A-1"
          [1]=>
          string(9) "ABC-12345"
          [2]=>
          string(7) "AB-2345"
          [3]=>
          string(5) "yz-33"
        }

          Blargh, yes, indeed. Just did it for myself. Thanks. I need a lunch break!

            Shouldn't have been using "\w" in the first place on this one, I think 😉

            It was imported from another function where it needed to be less restrictive.

              I'd recommend something I find a lot simpler in this case. Create a pattern consisting of a looh behind assertion for a-zA-Z and a look ahead assertion for 0-9. That is, you'll be matching the spot where a letter is followed by a didigt, and replace that spot with a -. That there isn't an actual character in that particular spot doesn't matter, it works anyway.

              $arr = array(
              	'abc123',
              	'ZY99',
              	'ASDDQWE4564',
              	'ASD',
              	'123',
              );
              
              $re = '#(?<=[a-zA-Z])(?=[0-9])#';
              
              foreach ($arr as $s)
              {
              	$out = preg_replace($re, '-', $s);
              	echo $out.'<br>';
              }
              
                Write a Reply...