попробуйте это:
([!@#$%^&*()]|(?:[.](?![a-z0-9]+$)))
с нечувствительным флагом «i». Заменить на '_'
Можно настроить первую партию символов или использовать \ W (любое не-слово)
так это читается как:
заменить на '_', где я соответствую, и этого набора, или точку, за которой не следуют некоторые символы или цифры и конец строки
Пример кода c #:
var newstr = new Regex("([!@#$%^&*()]|(?:[.](?![a-z0-9]+$)))", RegexOptions.IgnoreCase)
.Replace(myPath, "_");