diff --git a/include/libcamera/internal/device_enumerator.h b/include/libcamera/internal/device_enumerator.h
index db3532a9887af913ceee20cbba3f945e56e7b61d..fa8806b0c2a47ab89fdc74fe01ef77bf2e68abb1 100644
--- a/include/libcamera/internal/device_enumerator.h
+++ b/include/libcamera/internal/device_enumerator.h
@@ -11,6 +11,7 @@
 #include <string>
 #include <vector>
 
+#include <libcamera/base/regex.h>
 #include <libcamera/base/signal.h>
 
 namespace libcamera {
@@ -23,12 +24,14 @@ public:
 	DeviceMatch(const std::string &driver);
 
 	void add(const std::string &entity);
+	void add(const std::regex entity);
 
 	bool match(const MediaDevice *device) const;
 
 private:
 	std::string driver_;
 	std::vector<std::string> entities_;
+	std::vector<std::regex> entityRegexs_;
 };
 
 class DeviceEnumerator
diff --git a/src/libcamera/device_enumerator.cpp b/src/libcamera/device_enumerator.cpp
index ae17862f676310ef568e5331106ed661e84b5130..2911d5f0385f9765a2eafce2085d1fd627d94b95 100644
--- a/src/libcamera/device_enumerator.cpp
+++ b/src/libcamera/device_enumerator.cpp
@@ -53,7 +53,8 @@ LOG_DEFINE_CATEGORY(DeviceEnumerator)
  *
  * A DeviceMatch is created with a specific Linux device driver in mind,
  * therefore the name of the driver is a required property. One or more Entity
- * names can be added as match criteria.
+ * names (or regular expressions designed to match an entity name) can be added
+ * as match criteria.
  *
  * Pipeline handlers are recommended to add entities to DeviceMatch as
  * appropriate to ensure that the media device they need can be uniquely
@@ -81,6 +82,15 @@ void DeviceMatch::add(const std::string &entity)
 	entities_.push_back(entity);
 }
 
+/**
+ * \brief Add a regex to match a media entity name to the search pattern
+ * \param[in] entity The regex intended to match to an entity in the media graph
+ */
+void DeviceMatch::add(const std::regex entity)
+{
+	entityRegexs_.push_back(std::move(entity));
+}
+
 /**
  * \brief Compare a search pattern with a media device
  * \param[in] device The media device
@@ -116,6 +126,33 @@ bool DeviceMatch::match(const MediaDevice *device) const
 			return false;
 	}
 
+	for (const std::regex &nameRegex : entityRegexs_) {
+		bool found = false;
+
+		for (const MediaEntity *entity : device->entities()) {
+			if (!std::regex_search(entity->name(), nameRegex))
+				continue;
+
+			if (found) {
+				LOG(DeviceEnumerator, Error)
+					<< "Multiple entities match regex";
+				return false;
+			}
+
+			if (entity->deviceNode().empty()) {
+				LOG(DeviceEnumerator, Debug)
+					<< "Skip " << entity->name()
+					<< ": no device node";
+				continue;
+			}
+
+			found = true;
+		}
+
+		if (!found)
+			return false;
+	}
+
 	return true;
 }
 
