Brian,
Don't feel bad; it's a complicated thing you're trying to do.
We can suggest two solutions.
Here's the first one. It uses --init to define a subroutine (Perl syntax) that then can be called by the --group expression:
mrskew *.trc --init='sub f($) { my $x = $_[0]; for ($x) { s:/\*\+.*?\*/::g; }; return $x; }' --group='substr(f($sql), 0, 50)'
One subtlety to notice is in the regular expression /\*\+.*?\*/. The .*? construct calls for a non-greedy match. It makes the RE work correctly for a string like "select /*+ hint1 */ stuff /*+ hint2 */". Without the ?, the RE processor would have eaten the string " stuff " as well as both hints, which would give an incorrect result.
The second one is simpler:
mrskew *.trc --group='substr(($sql =~ s:/\*\+.*?\*/::g, $sql)[1], 0, 50)'
This one constructs a list of two elements. The first element executes the =~ operator, which returns a count of matches, but changes its lvalue. The second element references the changed value of $sql. The [1] appended to the list means to select only the 1th element of the list as the --group expression's ultimate value.
Note that it's important in
either case to do the substr() operator after the regular expression processing. Otherwise, you risk not having the closing */ delimiter in the string in which you're searching for hints.