You can tackle this problem from both sides, with a ckeditor plugin as @Sssweat suggested and on the drupal side with a filter plugin.
This is an example from core which adds classes to tags. This code looks for the attribute 'data-align', but you can also look for tags:
namespace Drupal\filter\Plugin\Filter;
use Drupal\Component\Utility\Html;
use Drupal\filter\FilterProcessResult;
use Drupal\filter\Plugin\FilterBase;
/**
* Provides a filter to align elements.
*
* @Filter(
* id = "filter_align",
* title = @Translation("Align images"),
* description = @Translation("Uses a <code>data-align</code> attribute on <code><img></code> tags to align images."),
* type = Drupal\filter\Plugin\FilterInterface::TYPE_TRANSFORM_REVERSIBLE
* )
*/
class FilterAlign extends FilterBase {
/**
* {@inheritdoc}
*/
public function process($text, $langcode) {
$result = new FilterProcessResult($text);
if (stristr($text, 'data-align') !== FALSE) {
$dom = Html::load($text);
$xpath = new \DOMXPath($dom);
foreach ($xpath->query('//*[@data-align]') as $node) {
// Read the data-align attribute's value, then delete it.
$align = $node->getAttribute('data-align');
$node->removeAttribute('data-align');
// If one of the allowed alignments, add the corresponding class.
if (in_array($align, array('left', 'center', 'right'))) {
$classes = $node->getAttribute('class');
$classes = (strlen($classes) > 0) ? explode(' ', $classes) : array();
$classes[] = 'align-' . $align;
$node->setAttribute('class', implode(' ', $classes));
}
}
$result->setProcessedText(Html::serialize($dom));
}
return $result;
}
}
The scaffolding of a custom filter module is very simple. See the tutorial:
https://www.lullabot.com/articles/creating-a-custom-filter-in-drupal-8