Lots of reasonable answers here, but I think the simplest approach is to sanitize the data in an INSTEAD OF trigger, which will fire before you actually insert the data. That way your AFTER triggers only fire once because you only modify the table once. EG
drop table if exists t
go
create table t(id int primary key, a varchar(20))
go
create or alter trigger t_II on t
instead of insert
as
begin
set nocount on
print 'instead of trigger running'
insert into t(id,a)
select id, trim(a) from inserted
end
go
create or alter trigger t_AI on t
after insert
as
begin
set nocount on
print 'after trigger running'
end
go
insert into t(id,a) values (1, ' a '),(2, ' a ')
outputs
instead of trigger running
after trigger running
(2 rows affected)