1) could used some examples of what you are parsing.
2) if use use "x" on the end of the expression, you can put white space and comments in the regular expression to make it more understandable
3) Also, by breaking it down, you'll notice that the second part of the stuff inside of ( ) was missing the match for numbers... instead looking for 0 or more '_', and breaking when it saw the numbers, thus not matching.
while(<TOCFILE>)
{
$toc_line = $_;
$toc_line =~
s/ # replace the follwoing
<inlineFig # match this text
.*? # then any characters until the next sequence matches
( # throw the match into $1
\.\.\/pics\/ch09_inline99_ # ..\pics\cho9_inline99_
\d*?\.jpg # folowed by 0 or more numbers
)*? # keeping doing that until the next sequence matches
<\/inlineFig> # match this text
/ # with the follwoing
<img src="${1}" alt="" \/\> # some text and the result of $1 above.
/xg; # <- the x makes it ignore whitespace and #comments
$new_toc_file .= $toc_line;
}
4) as mentioned, ()*? only returns the last match into $1, but this shouldn't be a problem if your input is only going to be of a certain format.