OK, should be straightforward. You need to set up a multidimensional array - or you can stick with your 3 arrays. However, it may be useful to place all the sharps first. This means that your replacement function will search for these first. If a match is made - you replace and then move on to the next part of the string. If you replaced with the 'normal' note, you'd end up incorrectly replacing a sharp note.
$trans = array(
'actual' = array("A#","C#"...),
'up' = array("B","D"...),
'down' = array("A","C"...)
);
You can use a preg_replace() function - although regex is still beyond me after all these years! So if you want to use that, look it up or perhaps a kind soul on this forum could give you a hand.
My own solution would be to:
This is pseudocode/procedure:
1. explode the string into lines (using the line break as a delimiter)
2. for each line - if it begins with a * - throw it into your transpose function **
3. implode the lines back into a full string
**I'm unsure if you have more than one note/key/chord/whatever in one line.
If just one chord
For each line: loop through the 'actual' and search for a match - if found - replace and exit the loop. Your substring search will need to be case sensitive.
If many chords in one line:
Explode the line using the 'space' as a delimiter - now loop over the bits and then implode back into a line.
Perhaps I've over-egged it?!