diff --git a/page_cache_query_ignore.services.yml b/page_cache_query_ignore.services.yml
new file mode 100644
index 0000000..634bc32
--- /dev/null
+++ b/page_cache_query_ignore.services.yml
@@ -0,0 +1,4 @@
+services:
+  page_cache_query_ignore.clean_query_string:
+    class: Drupal\page_cache_query_ignore\Service\CleanQueryString
+    arguments: ['@config.factory']
diff --git a/src/PageCacheQueryIgnoreServiceProvider.php b/src/PageCacheQueryIgnoreServiceProvider.php
index 1302f1d..f2943f3 100644
--- a/src/PageCacheQueryIgnoreServiceProvider.php
+++ b/src/PageCacheQueryIgnoreServiceProvider.php
@@ -17,7 +17,7 @@ class PageCacheQueryIgnoreServiceProvider extends ServiceProviderBase {
   public function alter(ContainerBuilder $container) {
     $definition = $container->getDefinition('http_middleware.page_cache');
     $definition->setClass('Drupal\page_cache_query_ignore\StackMiddleware\PageCacheIgnore')
-      ->addArgument(new Reference('config.factory'));
+      ->addArgument(new Reference('page_cache_query_ignore.clean_query_string'));
   }
 
 }
diff --git a/src/Service/CleanQueryString.php b/src/Service/CleanQueryString.php
new file mode 100644
index 0000000..93b2a85
--- /dev/null
+++ b/src/Service/CleanQueryString.php
@@ -0,0 +1,98 @@
+<?php
+
+namespace Drupal\page_cache_query_ignore\Service;
+
+use Drupal\Core\Config\ConfigFactoryInterface;
+
+class CleanQueryString {
+
+  /**
+   * A config object for the page cache query parameters ignore.
+   *
+   * @var \Drupal\Core\Config\Config
+   */
+  private $config;
+
+  /**
+   * Ignored parameters.
+   *
+   * @var array
+   */
+  private $ignoredParameters = [];
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct(ConfigFactoryInterface $config_factory) {
+    $this->config = $config_factory->get('page_cache_query_ignore.settings');
+  }
+
+  /**
+   * Get ignored query params.
+   *
+   * @return array
+   *   Ignored params.
+   */
+  public function getIgnoredParams() {
+    if (empty($this->ignoredParameters)) {
+      $this->ignoredParameters = $this->config->get('ignored_parameters');
+    }
+    return $this->ignoredParameters;
+  }
+
+  /**
+   * Clear query string with url attached.
+   *
+   * @param string $value
+   *   The value to cleanup.
+   *
+   * @return string
+   *   The cleared value.
+   */
+  public function clean($value) {
+    $url_and_query = explode('?', $value);
+
+    if (!isset($url_and_query[0]) || !isset($url_and_query[1])) {
+      return $value;
+    }
+
+    $raw_query = $url_and_query[1];
+    $clean_query = $this->cleanQueryOnly($raw_query);
+
+    if ($raw_query != $clean_query) {
+      return $url_and_query[0] . '?' . $clean_query;
+    }
+
+    return $value;
+  }
+
+  /**
+   * Clear query string.
+   *
+   * @param string $value
+   *   The value to cleanup.
+   *
+   * @return string
+   *   The cleared value.
+   */
+  public function cleanQueryOnly($raw_query) {
+    $exploded_raw_query = explode('&', $raw_query);
+
+    if (count($exploded_raw_query) > 0) {
+      $exploded_cleaned_query = [];
+      $params_to_ignore = $this->getIgnoredParams();
+
+      foreach ($exploded_raw_query as $current_raw_query) {
+        $key_value = explode('=', $current_raw_query);
+        if (!in_array(urldecode($key_value[0]), $params_to_ignore)) {
+          $exploded_cleaned_query[$key_value[0]] = $current_raw_query;
+        }
+      }
+
+      return implode('&', $exploded_cleaned_query);
+    }
+
+    return $raw_query;
+  }
+
+}
diff --git a/src/StackMiddleware/PageCacheIgnore.php b/src/StackMiddleware/PageCacheIgnore.php
index 9568c41..92b0cc3 100644
--- a/src/StackMiddleware/PageCacheIgnore.php
+++ b/src/StackMiddleware/PageCacheIgnore.php
@@ -3,10 +3,10 @@
 namespace Drupal\page_cache_query_ignore\StackMiddleware;
 
 use Drupal\Core\Cache\CacheBackendInterface;
-use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\PageCache\RequestPolicyInterface;
 use Drupal\Core\PageCache\ResponsePolicyInterface;
 use Drupal\page_cache\StackMiddleware\PageCache;
+use Drupal\page_cache_query_ignore\Service\CleanQueryString;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpKernel\HttpKernelInterface;
 
@@ -18,25 +18,18 @@ use Symfony\Component\HttpKernel\HttpKernelInterface;
 class PageCacheIgnore extends PageCache {
 
   /**
-   * A config object for the page cache query parameters ignore.
+   * A service used for cleaning a query string.
    *
-   * @var \Drupal\Core\Config\Config
+   * @var \Drupal\page_cache_query_ignore\Service\CleanQueryString
    */
-  protected $config;
-
-  /**
-   * Ignored parameters.
-   *
-   * @var array
-   */
-  protected $ignoredParameters = [];
+  protected $clean_query_string_service;
 
   /**
    * {@inheritdoc}
    */
-  public function __construct(HttpKernelInterface $http_kernel, CacheBackendInterface $cache, RequestPolicyInterface $request_policy, ResponsePolicyInterface $response_policy, ConfigFactoryInterface $config_factory) {
+  public function __construct(HttpKernelInterface $http_kernel, CacheBackendInterface $cache, RequestPolicyInterface $request_policy, ResponsePolicyInterface $response_policy, CleanQueryString $clean_query_string_service) {
     parent::__construct($http_kernel, $cache, $request_policy, $response_policy);
-    $this->config = $config_factory->get('page_cache_query_ignore.settings');
+    $this->clean_query_string_service = $clean_query_string_service;
   }
 
   /**
@@ -49,9 +42,10 @@ class PageCacheIgnore extends PageCache {
     // the request format might be NULL during cache lookup and then set during
     // routing, in which case we want to key on NULL during writing, since that
     // will be the value during lookups for subsequent requests.
+
     if (!isset($this->cid)) {
       $cid_parts = [
-        $request->getSchemeAndHttpHost() . $this->clear($request->getRequestUri()),
+        $request->getSchemeAndHttpHost() . $this->clean_query_string_service->clean($request->getRequestUri()),
         $request->getRequestFormat(NULL),
       ];
       $this->cid = implode(':', $cid_parts);
@@ -59,52 +53,4 @@ class PageCacheIgnore extends PageCache {
     return $this->cid;
   }
 
-  /**
-   * Get ignored query params.
-   *
-   * @return array
-   *   Ignored params.
-   */
-  protected function getIgnoredParams() {
-    if (empty($this->ignoredParameters)) {
-      $this->ignoredParameters = $this->config->get('ignored_parameters');
-    }
-    return $this->ignoredParameters;
-  }
-
-  /**
-   * Clear query string.
-   *
-   * @param string $value
-   *   The value to cleanup.
-   *
-   * @return string
-   *   The cleared value.
-   */
-  protected function clear($value) {
-    $value = preg_replace($this->getRegex(), '', $value);
-    $value = str_replace('?&', '?', $value);
-    $value = rtrim($value, '?');
-    return $value;
-  }
-
-  /**
-   * Generate regex to clear query string.
-   *
-   * @return string
-   *   The regex string.
-   */
-  protected function getRegex() {
-    $param_for_regex = [];
-
-    foreach ($this->getIgnoredParams() as $param) {
-      unset($_REQUEST[$param]);
-      unset($_GET[$param]);
-      $param_for_regex[] = "(?:[&]{0,1}{$param}=[^&]*)";
-    }
-    $ignode_trackers_params_regex = implode('|', $param_for_regex);
-    $regex = "/{$ignode_trackers_params_regex}/i";
-    return $regex;
-  }
-
 }
