diff --git a/src/Plugin/Condition/TextComparison.php b/src/Plugin/Condition/TextComparison.php
new file mode 100644
index 0000000..7cea6a1
--- /dev/null
+++ b/src/Plugin/Condition/TextComparison.php
@@ -0,0 +1,69 @@
+<?php
+
+namespace Drupal\rules\Plugin\Condition;
+
+use Drupal\rules\Core\RulesConditionBase;
+
+/**
+ * Provides a 'Text comparison' condition.
+ *
+ * @Condition(
+ *   id = "rules_text_comparison",
+ *   label = @Translation("Text comparison"),
+ *   category = @Translation("Data"),
+ *   context = {
+ *     "text" = @ContextDefinition("string",
+ *       label = @Translation("Text")
+ *     ),
+ *     "operator" = @ContextDefinition("string",
+ *       label = @Translation("Operator"),
+ *       description = @Translation("The comparison operator. One of 'contains', 'starts', 'ends', or 'regex'. Defaults to 'contains'."),
+ *       default_value = "contains",
+ *       required = FALSE
+ *     ),
+ *     "match" = @ContextDefinition("string",
+ *        label = @Translation("Matching text")
+ *     )
+ *   }
+ * )
+ */
+class TextComparison extends RulesConditionBase {
+
+  /**
+   * Evaluate the text comparison.
+   *
+   * @param string $text
+   *   The supplied text string.
+   * @param string $operator
+   *   Text comparison operator. One of:
+   *   - contains: (default) Evaluate if $text contains $match.
+   *   - starts: Evaluate if $text starts with $match.
+   *   - ends: Evaluate if $text ends with $match.
+   *   - regex: Evaluate if a regular expression in $match matches $text.
+   *   Values that do not match one of these operators default to "contains".
+   * @param string $match
+   *   The string to be compared against $text.
+   *
+   * @return bool
+   *   The evaluation of the condition.
+   */
+  protected function doEvaluate($text, $operator, $match) {
+    $operator = $operator ? $operator : 'contains';
+    switch ($operator) {
+      case 'starts':
+        return strpos($text, $match) === 0;
+
+      case 'ends':
+        return strrpos($text, $match) === (strlen($text) - strlen($match));
+
+      case 'regex':
+        return (bool) preg_match('/' . str_replace('/', '\\/', $match) . '/', $text);
+
+      case 'contains':
+      default:
+        // Default operator "contains".
+        return strpos($text, $match) !== FALSE;
+    }
+  }
+
+}
diff --git a/tests/src/Unit/Integration/Condition/TextComparisonTest.php b/tests/src/Unit/Integration/Condition/TextComparisonTest.php
new file mode 100644
index 0000000..8afa7ee
--- /dev/null
+++ b/tests/src/Unit/Integration/Condition/TextComparisonTest.php
@@ -0,0 +1,131 @@
+<?php
+
+namespace Drupal\Tests\rules\Unit\Integration\Condition;
+
+use Drupal\Core\TypedData\DataDefinition;
+use Drupal\Tests\rules\Unit\Integration\RulesIntegrationTestBase;
+
+/**
+ * @coversDefaultClass \Drupal\rules\Plugin\Condition\TextComparison
+ * @group RulesCondition
+ */
+class TextComparisonTest extends RulesIntegrationTestBase {
+
+  /**
+   * The condition to be tested.
+   *
+   * @var \Drupal\rules\Core\RulesConditionInterface
+   */
+  protected $condition;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp() {
+    parent::setUp();
+
+    $this->condition = $this->conditionManager->createInstance('rules_text_comparison');
+  }
+
+  /**
+   * Tests evaluating the condition with the "starts" operator.
+   *
+   * @covers ::evaluate
+   */
+  public function testConditionEvaluationOperatorStarts() {
+    // Test that when the text string starts with the match string and
+    // the operator is 'starts', TRUE is returned.
+    $this->condition
+      ->setContextValue('text', 'my-text')
+      ->setContextValue('operator', 'starts')
+      ->setContextValue('match', 'my');
+    $this->assertTrue($this->condition->evaluate());
+
+    // Test that when the text string does not start with the match string and
+    // the operator is 'starts', FALSE is returned.
+    $this->condition
+      ->setContextValue('text', 'my-text')
+      ->setContextValue('operator', 'starts')
+      ->setContextValue('match', 'text');
+    $this->assertFalse($this->condition->evaluate());
+  }
+
+  /**
+   * Tests evaluating the condition with the "ends" operator.
+   *
+   * @covers ::evaluate
+   */
+  public function testConditionEvaluationOperatorEnds() {
+    // Test that when the text string ends with the match string and
+    // the operator is 'ends', TRUE is returned.
+    $this->condition
+      ->setContextValue('text', 'my-text')
+      ->setContextValue('operator', 'ends')
+      ->setContextValue('match', 'text');
+    $this->assertTrue($this->condition->evaluate());
+
+    // Test that when the text string does not end with the match string and
+    // the operator is 'ends', FALSE is returned.
+    $this->condition
+      ->setContextValue('text', 'my-text')
+      ->setContextValue('operator', 'ends')
+      ->setContextValue('match', 'my');
+    $this->assertFalse($this->condition->evaluate());
+  }
+
+  /**
+   * Tests evaluating the condition with the "contains" operator.
+   *
+   * @covers ::evaluate
+   */
+  public function testConditionEvaluationOperatorContains() {
+    // Test that when the text string contains the match string and
+    // the operator is 'contains', TRUE is returned.
+    $this->condition
+      ->setContextValue('text', 'my-text')
+      ->setContextValue('operator', 'contains')
+      ->setContextValue('match', 'y-t');
+    $this->assertTrue($this->condition->evaluate());
+
+    // Test that when the text string does not contain the match string and
+    // the operator is 'contains', FALSE is returned.
+    $this->condition
+      ->setContextValue('text', 'my-text')
+      ->setContextValue('operator', 'contains')
+      ->setContextValue('match', 't-y');
+    $this->assertFalse($this->condition->evaluate());
+  }
+
+  /**
+   * Tests evaluating the condition with the "regex" operator.
+   *
+   * @covers ::evaluate
+   */
+  public function testConditionEvaluationOperatorRegex() {
+    // Test that when the operator is 'regex' and the regular expression in
+    // the match string matches the text string, TRUE is returned.
+    $this->condition
+      ->setContextValue('text', 'my-text')
+      ->setContextValue('operator', 'regex')
+      ->setContextValue('match', 'me?y-texx?t');
+    $this->assertTrue($this->condition->evaluate());
+
+    // Test that when the operator is 'regex' and the regular expression in
+    // the match string does not matche the text string, TRUE is returned.
+    $this->condition
+      ->setContextValue('text', 'my-text')
+      ->setContextValue('operator', 'regex')
+      ->setContextValue('match', 'me+y-texx?t');
+    $this->assertFalse($this->condition->evaluate());
+  }
+
+  /**
+   * Tests the summary.
+   *
+   * @covers ::summary
+   */
+  public function testSummary() {
+    $this->assertEquals('Text comparison', $this->condition->summary());
+  }
+
+}
