Repository: prometheus/prometheus (language: go)

Issue:
KeepEqual/DropEqual should compare Regex.String instead of instance values
### What did you do?

Using a relabel config with keepequal/dropequal compares instance var instead of string value.

https://github.com/prometheus/prometheus/blob/main/model/relabel/relabel.go#L134 should be `c.Regex.String() != DefaultRelabelConfig.Regex.String()` and not `c.Regex != DefaultRelabelConfig.Regex`

### What did you expect to see?

_No response_

### What did you see instead? Under which circumstances?

KeepEqual doesn't work if we the regex is the same string but different instance.

### System information

_No response_

### Prometheus version

_No response_

### Prometheus configuration file

```yaml
relabel_configs:
            - source_labels: [label_1]
              action: keepequal
              target_label: label_2
```
```


### Alertmanager version

_No response_

### Alertmanager configuration file

_No response_

### Logs

_No response_


Discussion / hints:
I don't think it's enough to assert the code "should be different".
When I read the code, I see the point of the check is to check if the data has been changed from the default.
Can you show in a test how this can happen if the user didn't specify a regex?
Afaik, there's no test covering this issue on `grafana/agent`: it was reported by user as GH [issue](https://github.com/grafana/alloy/issues/415).

The patch managed to fix the reported issue.
I believe this is related: https://github.com/prometheus/prometheus/pull/12527#issuecomment-1829677659

Fix patch:
diff --git a/model/relabel/relabel.go b/model/relabel/relabel.go
index d29c3d07aeb..3b42492342d 100644
--- a/model/relabel/relabel.go
+++ b/model/relabel/relabel.go
@@ -205,6 +205,11 @@ func (re Regexp) MarshalYAML() (interface{}, error) {
 	return nil, nil
 }
 
+// IsZero implements the yaml.IsZeroer interface.
+func (re Regexp) IsZero() bool {
+	return re.Regexp == DefaultRelabelConfig.Regex.Regexp
+}
+
 // String returns the original string used to compile the regular expression.
 func (re Regexp) String() string {
 	str := re.Regexp.String()


Test patch:
diff --git a/model/relabel/relabel_test.go b/model/relabel/relabel_test.go
index 6798fb02a57..d694982ec98 100644
--- a/model/relabel/relabel_test.go
+++ b/model/relabel/relabel_test.go
@@ -851,3 +851,52 @@ func BenchmarkRelabel(b *testing.B) {
 		})
 	}
 }
+
+func TestConfig_UnmarshalThenMarshal(t *testing.T) {
+	tests := []struct {
+		name      string
+		inputYaml string
+	}{
+		{
+			name: "Values provided",
+			inputYaml: `source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port]
+separator: ;
+regex: \\d+
+target_label: __meta_kubernetes_pod_container_port_number
+replacement: $1
+action: replace
+`,
+		},
+		{
+			name: "No regex provided",
+			inputYaml: `source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port]
+separator: ;
+target_label: __meta_kubernetes_pod_container_port_number
+replacement: $1
+action: keepequal
+`,
+		},
+		{
+			name: "Default regex provided",
+			inputYaml: `source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port]
+separator: ;
+regex: (.*)
+target_label: __meta_kubernetes_pod_container_port_number
+replacement: $1
+action: replace
+`,
+		},
+	}
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			unmarshalled := Config{}
+			err := yaml.Unmarshal([]byte(test.inputYaml), &unmarshalled)
+			require.NoError(t, err)
+
+			marshalled, err := yaml.Marshal(&unmarshalled)
+			require.NoError(t, err)
+
+			require.Equal(t, test.inputYaml, string(marshalled))
+		})
+	}
+}