Как-то так может помочь:
const string = '&a.b.c. &a.b.c& .&a.b.c.&. *;a.b.c&*. a.b&.c& .&a.b.&&dc.& &ê.b..c&';
const result = string.split(' ').map(s => /^[^a-zA-Z0-9ê]*([\w\W]*?)[^a-zA-Z0-9ê]*$/g.exec(s)[1]).join(' ');
console.log(result);
Обратите внимание, что это не одно регулярное выражение, а использует код помощи JS.
Грубое объяснение: Сначала мы разбиваем строку на массив строк,разделены пробелами. Затем мы преобразуем каждую из подстрок, удаляя начальные и конечные специальные символы. Мы делаем это путем захвата всех специальных символов с помощью [^a-zA-Z0-9ê]*
, поскольку из-за ведущего символа ^
он совпадает со всеми символами , за исключением из перечисленных, то есть со всеми специальными символами. Между этими двумя группами мы фиксируем все соответствующие символы с ([\w\W]*?)
. \w
ловит слова, \W
ловит не слова, поэтому \w\W
ловит все возможные символы. Добавляя ?
после *
, мы делаем ленивый квантификатор *
, так что группа перестает ловить, как только следующая группа, которая ловит висячие специальные символы, что-то ловит. Мы также начинаем регулярное выражение с символа ^
и заканчиваем его символом $
, чтобы захватить всю строку (они соответственно устанавливают привязки на начало и конец строки). С .exec(s)[1]
мы затем выполняем регулярное выражение для подстроки и возвращаем первый результат группы захвата в нашей функции преобразования. Обратите внимание, что это может быть нулевым, если подстрока не содержит правильных символов. В конце мы соединяем подстроки пробелами.