Hey guys I'm a complete php newb and im looking from some help with the following script... thanks

	$search = '/[A-G\Z](m|#|9|maj|7|)(\/[A-G](m|#|9|maj|7|)?)?/';

$c = array('C', 'Db', 'D', 'Eb', 'E', 'F', 'F#', 'G', 'Ab', 'A', 'Bb', 'B');
$d = array('D', 'Eb', 'E', 'F', 'F#', 'G', 'Ab', 'A', 'Bb', 'B','C', 'C#');
preg_match_all($search, $song, $matches);

print_r($matches[0][0]);

$match = count($matches[0]);
for ($i=0; $i < $match; $i++) { 
	$new = str_replace($c, $d, $matches[0][$i]);
	echo $new . '<br/>';
	}

Im searching in a string with chords. Even though i know that my regular expression isn't the best it return a array with the chords ($matches).

When i try to replace $matches from C to D(even chord to it's relative chord) all I get back it C# for almost everything.

Whats wrong this isn't working like it's supposed to?

    22 days later
    krisnrg;10899636 wrote:

    Hey guys I'm a complete php newb and im looking from some help with the following script... thanks

    	$search = '/[A-G\Z](m|#|9|maj|7|)(\/[A-G](m|#|9|maj|7|)?)?/';
    
    $c = array('C', 'Db', 'D', 'Eb', 'E', 'F', 'F#', 'G', 'Ab', 'A', 'Bb', 'B');
    $d = array('D', 'Eb', 'E', 'F', 'F#', 'G', 'Ab', 'A', 'Bb', 'B','C', 'C#');
    preg_match_all($search, $song, $matches);
    
    print_r($matches[0][0]);
    
    $match = count($matches[0]);
    for ($i=0; $i < $match; $i++) { 
    	$new = str_replace($c, $d, $matches[0][$i]);
    	echo $new . '<br/>';
    	}
    

    Im searching in a string with chords. Even though i know that my regular expression isn't the best it return a array with the chords ($matches).

    When i try to replace $matches from C to D(even chord to it's relative chord) all I get back it C# for almost everything.

    Whats wrong this isn't working like it's supposed to?

    I was looking for a regular expression to do the same thing...I am good with php but not so good with RegEx.
    Your main issue was that you were telling it to look for the array "$c" and replace it with the array "$d". What you need to do is find the correct item in the array and replace it with the corresponding correct item from the second array.
    Also, I noticed that chords that had an m or maj7, etc. were not getting replaced correctly, because those were not in the array, so I added some code to remove those and then add them back, after the transposition. (You will need to add the rest, I just did two.)
    Seems to be working pretty good.
    The next step will be to get the chords put back in their proper location in the tab and to rework the regular expression to only get chords that are not in the lyrics in the tab.
    I'm probably going to keep working on this, and if I get it, I'll post it.
    Have fun!

    $search = '/[A-G\Z](m|#|9|maj|7|)(\/[A-G](m|#|9|maj|7|)?)?/';
    
    $c = array('C', 'Db', 'D', 'Eb', 'E', 'F', 'F#', 'G', 'Ab', 'A', 'Bb', 'B');
    $d = array('D', 'Eb', 'E', 'F', 'F#', 'G', 'Ab', 'A', 'Bb', 'B','C', 'C#');
    preg_match_all($search, $song, $matches);
    
    print_r($matches[0]);
    
    $match = count($matches[0]);
    $i = 0;
    foreach ($matches[0] as $key=>$value) {
    	$chord = $matches[0][$i];
    	$additional = "";
    	if (strstr($chord, "m")) {
    		$chord = str_replace("m", "", $chord);
    		$additional = "m";
    	} elseif (strstr($chord, "m")) {
    		$chord = str_replace("maj7", "", $chord);
    		$additional = "maj7";
    	}
    	$position = array_search($chord, $c);
    
    $new = str_replace($c[$position], $d[$position], $chord);
    $new .= $additional;
    echo '<br />' . $new;
    $i++;
    }
    

      This is something I was playing around with some time ago which might apply to at least the transposition part of things:

      <?php
      /**
       * Transpose musical notes/keys
       **/
      class Transposer
      {
         /**
          * @var string "flats" or "sharps"
          **/
         private $type = 'flats';
      
         /**
          * @var array All the note data
          **/
         private $notes = array(
            'scale' => array(
               'B#' => 1,
               'C'  => 1,
               'C#' => 2,
               'Db' => 2,
               'D'  => 3,
               'D#' => 4,
               'Eb' => 4,
               'E'  => 5,
               'Fb' => 5,
               'E#' => 6,
               'F'  => 6,
               'F#' => 7,
               'Gb' => 7,
               'G'  => 8,
               'G#' => 9,
               'Ab' => 9,
               'A'  => 10,
               'A#' => 11,
               'Bb' => 11,
               'B'  => 12,
               'Cb' => 12
            ),
            'flats'  => array(1 => 'C', 'Db', 'D', 'Eb', 'E', 'F', 'Gb', 'G', 'Ab', 'A', 'Bb', 'B'),
            'sharps' => array(1 => 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B')
         );
      
         /**
          * Set whether we want flatted or sharped notes/keys
          * @return bool
          * @param $type string 'b' or 'flat[s]' for flats, '#' or 'sharp[s]' for sharps
          **/
         public function setType($type)
         {
            if(in_array(strtolower($type), array('b', 'flat', 'flats')))
            {
               $this->type = 'flats';
            }
            elseif(in_array(strtolower($type), array('#', 'sharp', 'sharps')))
            {
               $this->type = 'sharps';
            }
            else
            {
               user_error("Invalid value '$type'");
               return false;
            }
            return true;
         }
      
         /**
          * Get the current type
          * @return string
          **/
         public function getType()
         {
            return($this->type);
         }
      
         /**
          * Transpose a note
          * @return string
          * @param string $note "C", "Eb", "F#", etc.
          * @param int $steps Half-steps to be trasponsed, -11 to 11
          **/
         public function transpose($note, $steps)
         {
            $steps = (int)$steps;
            if($steps > 11 or $steps < -11)
            {
               user_error("Invalid number of half-steps '$steps' (must be -11 to 11)");
               return false;
            }
            $note[0] = strtoupper($note[0]);
            if(isset($this->notes['scale'][$note]))
            {
               $ix = $this->notes['scale'][$note];
            }
            else
            {
               user_error("Invalid note '$note'");
               return false;
            }
            $ixNew = $ix + $steps;
            if(!isset($this->notes[$this->type][$ixNew]))
            {
               $ixNew += ($ixNew > 0) ? -12 : 12;
               if(!isset($this->notes[$this->type][$ixNew]))
               {
                  throw new Exception("My math skills suck! $note : $steps : $ix : $ixNew");
               }
            }
            return($this->notes[$this->type][$ixNew]);
         }
      }
      
      // TEST:
      try
      {
         $tr = new Transposer();
         echo "<pre>";
         foreach(array('flats', 'sharps') as $fs)
         {
            $tr->setType($fs);
            echo "#### $fs ####\n";
            foreach(array('A', 'Bb', 'B', 'C', 'Db', 'D', 'Eb', 'E', 'F', 'Gb', 'G', 'Ab') as $key)
            {
               echo "  $key:\n";
               for($n = -11; $n < 12; $n++)
               {
                  printf("    &#37;3d = %s\n", $n, $tr->transpose($key, $n));
               }
            }
         }
         echo "</pre>";
      }
      catch(Exception $e)
      {
         echo "<pre>".print_r($e,1)."</pre>";
      }
      

        This don't remember what was wrong with this one... But on this one I just use two array and just offset them to get the correct note everytime...

        I think the problem is getting the array with the new values to substitute the right things inside the song string...

        Also is there a way to keep the song formatting the same? I mean they have to use spaces to put the chords above the word they want. I want the song string to come back with the same space and returns...

        // this needs the original key, new key and the song. Returns the song with the new chords...
        function transpose($key,$newKey,$song)
        {

            $search = '/[A-G\Z](m|#|9|maj|7|)(\/[A-G](m|#|9|maj|7|)?)?/'; 
            preg_match_all($search, $song, $song_chords); 
            $u = array_unique($song_chords[0]);
            print_r($u);
        
        
            $note = array('/(?<!\|)C/','/(?<!\|)C#/', '/(?<!\|)D/','/(?<!\|)D#/', '/(?<!\|)E/', '/(?<!\|)F/','/(?<!\|)F#/','/(?<!\|)G/','/(?<!\|)G#/', '/(?<!\|)A/','/(?<!\|)A#/', '/(?<!\|)B/');                
            $note = array_merge($note,$note);
            $note = array_slice($note,$key,12);
        
        
            $newNote = array('|C','|C#', '|D','|D#', '|E','|F','|F#', '|G','|G#','|A','|A#', '|B');                
            $newNote = array_merge($newNote,$newNote);
            $newNote = array_slice($newNote,$newKey,12);
        
        
            $new = preg_replace($note, $newNote, $u);
        //    print_r($song_chords[0]);
            $clean = str_replace('|', '', $new);    
            $new_song = str_replace($u, $clean, $song);    
            print_r($clean);
        
            echo $new_song;
        
        
        
        
            }
        
            echo transpose(0,4,$song2); [/QUOTE]
          krisnrg;10902279 wrote:

          Also is there a way to keep the song formatting the same? I mean they have to use spaces to put the chords above the word they want. I want the song string to come back with the same space and returns...

          I will look at the code tonight and see how it works...but to take care of this part, all I was doing is doing:

          echo str_replace(" ", "&nbsp;", $transposed_song);
          

            Thanks NogDog for the class you posted but i will continue to try to fix this cause thats the only way to learn....

            @ joshjryan
            try this version instead

            At the bottom just plug in:

            param1 = original key: in the form of a number C = 0, C#=1, D=2 and so on.

            param2 = Plug in the desired key also as an interger

            param3 = song to transpose

            param4 = specify if it's minor or major. Minor being 'true'(boolean)

            param5 = weather the results come back as the default flats or sharp. for sharp pass in 'sharp'

            I haven't look at this script in a while so im not sure if params 4 and 5 are working...

            Im trying to build a mini planningcenteronline.com for my church...

            <?php
            
            // this needs the original key, new key and the song. Returns the song with the new chords...
                function transpose($key,$newKey,$song,$minor=FALSE,$type='sharp')
                    {
                   	 function shift_values($param,$number)
            				{
            				  $param = array_merge($param,$param);
            			      $param = array_slice($param,$number,12);
            				  return $param;
            				}
            
            	//  preg pettenrs([A-G](#|b)*([a-z]|[0-9])*)(/[A-G](#|b)*([a-z]|[0-9])*)*
            	//	pattern (mine) \b[A-G]{1,1}(#|b)?(m|9|maj|7|sus)?(\/[A-G](#)?(b{1,1})?)?
                $search = '`\b[A-G]{1,1}(#|b)?(m|9|maj|7|sus)?(\/[A-G](#)?(b{1,1})?)?`'; 
                preg_match_all($search, $song, $song_chords); 
                $u = array_unique($song_chords[0]);
            	print_r($u);
            
                // Majors with sharps   
                $notes = array('/(?<!\|)C(?!(\#|b))/',
            					'/(?<!\|)(C#|Db)/',
            					'/(?<!\|)D(?!(\#|b))/',
            					'/(?<!\|)(D#|Eb)/',
            					'/(?<!\|)E(?!(\#|b))/',
            					'/(?<!\|)F(?!(\#|b))/',
            					'/(?<!\|)(F#|Gb)/',
            					'/(?<!\|)G(?!(\#|b))/',
            					'/(?<!\|)(G#|Ab)/',
            					'/(?<!\|)A(?!(\#|b))/',
            					'/(?<!\|)(A#|Bb)/',
            					'/(?<!\|)B(?!(\#|b))/');                
            	$notes = shift_values($notes,$key);
            
            	// Majors replace with sharps 
            	$sharps_replace = array('|C','|C#', '|D','|D#', '|E','|F','|F#', '|G','|G#','|A','|A#', '|B');                
            	$sharps_replace = shift_values($sharps_replace,$newKey);
            
            
            	// Majors replace with flats   
            	$flats_replace = array('|C','|Db', '|D','|Eb', '|E','|F','|Gb', '|G','|Ab','|A','|Bb', '|B');                
            	$flats_replace = shift_values($flats_replace,$newKey);
            
            	// Minors  
                $minors = array('/(?<!\|)C(?!(\#|b))/',
            					'/(?<!\|)(C#|Db)/',
            					'/(?<!\|)D(?!(\#|b))/',
            					'/(?<!\|)(D#|Eb)/',
            					'/(?<!\|)E(?!(#|b))/',
            					'/(?<!\|)F(?!(\#|b))/',
            					'/(?<!\|)(F#|Gb)/',
            					'/(?<!\|)G(?!(\#|b))/',
            					'/(?<!\|)(G#|Ab)/',
            					'/(?<!\|)A(?!(\#|b))/',
            					'/(?<!\|)(A#|Bb)/',
            					'/(?<!\|)B(?!(\#|b))/');                
            	$minors = shift_values($minors,$key);
            
            	// Minors replace with sharps
            	$minors_replace = array('|A','|A#', '|B','|C','|C#', '|D','|D#', '|E','|F','|F#', '|G','|G#');                
            	$minors_replace = shift_values($minors_replace,$newKey);
            
            	// Minors replace with flats
            	$minors_replace = array('|A','|Bb', '|B','|C','|Db', '|D','|Eb', '|E','|F','|Gb', '|G','|Ab');                
            	$minors_replace = shift_values($minors_replace,$newKey);
            
            	//check if it's minor or major
            
            	if ($minor == TRUE) {
            		$new = preg_replace($minors, $minors_replace, $u);
            	}
            	else if ($type == "flat" | $newKey == '3') {
            		$new = preg_replace($notes, $flats_replace, $u);
            	}
            	else {
            		$new = preg_replace($notes, $sharps_replace, $u);
            		}
            	print_r($new);
            
            	foreach ($u as $key => $value) {
            			$u[$key] = '/\b(?<!\|)'. preg_quote($value, '/') .'\b/';
            			}
            	print_r($u);
                $new_song = preg_replace($u, $new, $song);
                $clean = str_replace('|', '', $new_song);  
               	echo $clean;
            
            }
            echo transpose(2,4,$song3);
            
            ?>
              Write a Reply...