Index: src/wp-includes/comment.php
===================================================================
--- src/wp-includes/comment.php	(revision 42879)
+++ src/wp-includes/comment.php	(working copy)
@@ -3274,3 +3274,80 @@
 
 	return get_comment( $comment_id );
 }
+
+/**
+ * Registers the personal data exporter for comments
+ *
+ * @param array   $exporters   An array of personal data exporters.
+ * @return array  An array of personal data exporters.
+ */
+function wp_register_comment_personal_data_exporter( $exporters ) {
+	$exporters[] = array(
+		'exporter_friendly_name' => __( 'WordPress Comments' ),
+		'callback'               => 'wp_comments_personal_data_exporter',
+	);
+
+	return $exporters;
+}
+
+/**
+ * Finds and exports data which could be used to identify a person from comments assocated with an email address.
+ *
+ * @param string  $email  The comment author email address.
+ * @param int     $page   Comment page, zero based.
+ * @return array  An array of personal data in name value pairs
+ */
+function wp_comments_personal_data_exporter( $email_address, $page = 0 ) {
+
+	// Technically, strtolower isn't necessary since get_comments will match email insensitive
+	// But it is a good example for plugin developers whose targets might not be as generous
+	$email_address = trim( strtolower( $email_address ) );
+
+	// Limit us to 500 comments at a time to avoid timing out
+	$number = 500;
+	$offset = $number * (int) $page;
+
+	$comments = get_comments(
+		array(
+			'author_email' => $email_address,
+			'number'       => $number,
+			'offset'       => $offset,
+			'order_by'     => 'comment_ID',
+			'order'        => 'ASC',
+		)
+	);
+
+	$comment_personal_data_props = array(
+		'comment_author'       => __( 'Comment Author' ),
+		'comment_author_email' => __( 'Comment Author Email' ),
+		'comment_author_url'   => __( 'Comment Author URL' ),
+		'comment_author_IP'    => __( 'Comment Author IP' ),
+		'comment_agent'        => __( 'Comment Agent' ),
+	);
+
+	$personal_data = $compare = array_fill_keys( array_keys( $comment_personal_data_props ), array() );
+
+	foreach ( $comment_personal_data_props as $key => $name ) {
+		$personal_data[ $key ] = array( 'name' => $name, 'values' => array() );
+	}
+
+	foreach ( (array) $comments as $comment ) {
+		foreach ( $comment_personal_data_props as $key => $name ) {
+			$value = $comment->$key;
+
+			if ( ! empty( $value ) && ! in_array( $value, $compare[ $key ], true ) ) {
+				// Add the value to the comparison array...
+				$compare[ $key ][] = $value;
+				// and to the data export.
+				$personal_data[ $key ]['values'][] = $value;
+			}
+		}
+	}
+
+	$done = count( $comments ) < $number;
+
+	return array(
+		'data' => $personal_data,
+		'done' => $done,
+	);
+}
Index: src/wp-includes/default-filters.php
===================================================================
--- src/wp-includes/default-filters.php	(revision 42879)
+++ src/wp-includes/default-filters.php	(working copy)
@@ -328,6 +328,7 @@
 add_action( 'do_pings', 'do_all_pings', 10, 1 );
 add_action( 'do_robots', 'do_robots' );
 add_action( 'set_comment_cookies', 'wp_set_comment_cookies', 10, 3 );
+add_filter( 'wp_privacy_personal_data_exporters', 'wp_register_comment_personal_data_exporter', 10 );
 add_action( 'sanitize_comment_cookies', 'sanitize_comment_cookies' );
 add_action( 'admin_print_scripts', 'print_emoji_detection_script' );
 add_action( 'admin_print_scripts', 'print_head_scripts', 20 );
