Repository: prometheus/prometheus (language: go)

Issue:
docs: Make it clearer that regexps are always fully anchored
### What did you do?

I have a metric with a label. The label name is long, and I want to replace it with a shorter one.

```
feign_Client_seconds_max{application="my-backend", client="my.application.has.a.long.package.name.FeignClient", method="getInfo", uri="/rest/{blah}/something/{else}"}
```

I have written a regex that correctly matches `FeignClient` from the 'client' label: `([^\.]+)$`

I have tested this regex online, and it works correctly: https://regex101.com/r/E5rpSs/1

However, when I try entering this regex into Prometheus, I do not get any message at all. Prometheus just ignores the [label_replace](https://prometheus.io/docs/prometheus/latest/querying/functions/#label_replace) function and returns the data as if I hadn't done anything.

```
label_replace(feign_Client_seconds_max, "client_name", "$1", "client", "([^\\.]+)$")
```


```
feign_Client_seconds_max{application="my-backend", client="my.application.has.a.long.package.name.FeignClient", method="getInfo", uri="/rest/{blah}/something/{else}"}
```

### What did you expect to see?


```
feign_Client_seconds_max{application="my-backend", client_name="FeignClient", method="getInfo", uri="/rest/{blah}/something/{else}"}
```

### What did you see instead? Under which circumstances?


```
feign_Client_seconds_max{application="my-backend", client="my.application.has.a.long.package.name.FeignClient", method="getInfo", uri="/rest/{blah}/something/{else}"}
```

### System information

n/a

### Prometheus version

```text
Docker Prometheus v2.39.1
```


### Prometheus configuration file

```yaml
n/a
```


### Alertmanager version

```text
n/a
```


### Alertmanager configuration file

```yaml
n/a
```


### Logs

```text
n/a
```



Discussion / hints:
From https://prometheus.io/docs/prometheus/latest/querying/basics/:

`Regex matches are fully anchored. A match of env=~"foo" is treated as env=~"^foo$".`

So when you write `"([^\\.]+)$"` prometheus will actually use `"^([^\\.]+)$$"`.
> From https://prometheus.io/docs/prometheus/latest/querying/basics/:
> 
> `Regex matches are fully anchored. A match of env=~"foo" is treated as env=~"^foo$".`
> 
> So when you write `"([^\\.]+)$"` prometheus will actually use `"^([^\\.]+)$$"`.

Thanks, I'll try that. But those docs only look like they're for label matching, not for functions like `label_replace()`.

It would be helpful to have a specific section in the docs, with a header that can be linked to. It would be more visible if there's a specific 'regex' section in the TOC, and also where regexes are mentioned in other docs, they contain a link directly to the relevant section.
Hello from the bug scrub!

This is a documentation issue. Regexps are always fully anchored, and it would be good to state this visibly, maybe by adding this hint everywhere where regexps are used or, as proposed above, have some section in the basics that can be linked. PRs welcome.
I'd like to work on this 

Fix patch:
diff --git a/docs/querying/basics.md b/docs/querying/basics.md
index 1c06afb85d4..c1c76e7e049 100644
--- a/docs/querying/basics.md
+++ b/docs/querying/basics.md
@@ -37,7 +37,7 @@ Depending on the use-case (e.g. when graphing vs. displaying the output of an
 expression), only some of these types are legal as the result of a
 user-specified expression. 
 For [instant queries](api.md#instant-queries), any of the above data types are allowed as the root of the expression.
-[Range queries](api.md/#range-queries) only support scalar-typed and instant-vector-typed expressions.
+[Range queries](api.md#range-queries) only support scalar-typed and instant-vector-typed expressions.
 
 _Notes about the experimental native histograms:_
 
@@ -152,7 +152,7 @@ The value returned will be that of the most recent sample at or before the
 query's evaluation timestamp (in the case of an
 [instant query](api.md#instant-queries))
 or the current step within the query (in the case of a
-[range query](api.md/#range-queries)).
+[range query](api.md#range-queries)).
 The [`@` modifier](#modifier) allows overriding the timestamp relative to which
 the selection takes place. Time series are only returned if their most recent sample is less than the [lookback period](#staleness) ago.
 
@@ -178,7 +178,7 @@ against regular expressions. The following label matching operators exist:
 * `=~`: Select labels that regex-match the provided string.
 * `!~`: Select labels that do not regex-match the provided string.
 
-Regex matches are fully anchored. A match of `env=~"foo"` is treated as `env=~"^foo$"`.
+[Regex](#regular-expressions) matches are fully anchored. A match of `env=~"foo"` is treated as `env=~"^foo$"`.
 
 For example, this selects all `http_requests_total` time series for `staging`,
 `testing`, and `development` environments and HTTP methods other than `GET`.
@@ -241,9 +241,6 @@ A workaround for this restriction is to use the `__name__` label:
 
     {__name__="on"} # Good!
 
-All regular expressions in Prometheus use [RE2
-syntax](https://github.com/google/re2/wiki/Syntax).
-
 ### Range Vector Selectors
 
 Range vector literals work like instant vector literals, except that they
@@ -365,6 +362,12 @@ PromQL supports line comments that start with `#`. Example:
 
         # This is a comment
 
+## Regular expressions
+
+All regular expressions in Prometheus use [RE2 syntax](https://github.com/google/re2/wiki/Syntax).
+
+Regex matches are always fully anchored.
+
 ## Gotchas
 
 ### Staleness
diff --git a/docs/querying/examples.md b/docs/querying/examples.md
index 8287ff6f628..1879a9945c9 100644
--- a/docs/querying/examples.md
+++ b/docs/querying/examples.md
@@ -25,14 +25,11 @@ for the same vector, making it a [range vector](../basics/#range-vector-selector
 Note that an expression resulting in a range vector cannot be graphed directly,
 but viewed in the tabular ("Console") view of the expression browser.
 
-Using regular expressions, you could select time series only for jobs whose
+Using [regular expressions](./basics.md#regular-expressions), you could select time series only for jobs whose
 name match a certain pattern, in this case, all jobs that end with `server`:
 
     http_requests_total{job=~".*server"}
 
-All regular expressions in Prometheus use [RE2
-syntax](https://github.com/google/re2/wiki/Syntax).
-
 To select all HTTP status codes except 4xx ones, you could run:
 
     http_requests_total{status!~"4.."}
diff --git a/docs/querying/functions.md b/docs/querying/functions.md
index 310b7b9337d..facdfce154d 100644
--- a/docs/querying/functions.md
+++ b/docs/querying/functions.md
@@ -598,7 +598,7 @@ label_join(up{job="api-server",src1="a",src2="b",src3="c"}, "foo", ",", "src1",
 ## `label_replace()`
 
 For each timeseries in `v`, `label_replace(v instant-vector, dst_label string, replacement string, src_label string, regex string)`
-matches the [regular expression](https://github.com/google/re2/wiki/Syntax) `regex` against the value of the label `src_label`. If it
+matches the [regular expression](./basics.md#regular-expressions) `regex` against the value of the label `src_label`. If it
 matches, the value of the label `dst_label` in the returned timeseries will be the expansion
 of `replacement`, together with the original labels in the input. Capturing groups in the
 regular expression can be referenced with `$1`, `$2`, etc. Named capturing groups in the regular expression can be referenced with `$name` (where `name` is the  capturing group name). If the regular expression doesn't match then the timeseries is returned unchanged.


Test patch: