Non-empty string as route parameter
As long as a default value isn't provided in the route definition, every route placeholder is required. Defining the route as follow is sufficient.
my.search.results:
  path: '/search/{text}'
  defaults:
    _controller: '\Drupal\my\Controller\SearchController::results'
    _title: 'Search Results'
  requirements:
    _permission: 'access content

See, for example, the definition of the dblog.event route in the dblog.routing.yml file.
dblog.event:
  path: '/admin/reports/dblog/event/{event_id}'
  defaults:
    _controller: '\Drupal\dblog\Controller\DbLogController::eventDetails'
    _title: 'Details'
  requirements:
    _permission: 'access site reports'

The controller associated to that route, DbLogController::eventDetails(), doesn't check the value of $event_id is an empty string, simply because it won't get an empty string for that parameter.
public function eventDetails($event_id) {
  $dblog = $this-&gt;database-&gt;query('SELECT w.*, u.uid FROM {watchdog} w LEFT JOIN {users} u ON u.uid = w.uid WHERE w.wid = :id', [
    ':id' =&gt; $event_id,
  ])
    -&gt;fetchObject();
  if (empty($dblog)) {
    throw new NotFoundHttpException();
  }
  // …
}