1

I've found that \A can be emulated with:

(?<!\s)^

and PCRE(2)/re2 \z (Python \Z) can be emulated with:

$(?!\s)

regex101 demo

How else can \A and/or \z be emulated in JS?

Even regular-expression.info has no mention of what I've presented.

MonkeyZeus
  • 20,375
  • 4
  • 36
  • 77
  • 1
    Make it singleline instead of multiline and then use [`^|$`](https://regex101.com/r/I3TGRR/1)? – Gurmanjot Singh Jan 06 '22 at 14:06
  • @GurmanjotSingh Sorry, I forgot about `/s`. It's relatively new to JS so I'd like to avoid it as well. – MonkeyZeus Jan 06 '22 at 14:11
  • 1
    You can then get them from group 1 and group 2. [`(^)[\s\S]*($)`](https://regex101.com/r/XvsTQG/1). Group 1 contains `\A` and group 2 contains `\Z` – Gurmanjot Singh Jan 06 '22 at 14:16
  • @GurmanjotSingh Very creative. I'd love it if you could post these solutions as answers. My inspiration for asking this question stems from my recent answer here https://stackoverflow.com/a/70608182/2191572 – MonkeyZeus Jan 06 '22 at 14:20
  • 1
    Are you silently saying you are using the `m` flag? If not, then `^` and `$` already act like this by default in JS. – trincot Jan 06 '22 at 14:21
  • I'm considering turning this into a Wiki because even the best of my Google-ability keeps yielding results for `^` and `$`. I think many people don't know the existence of `\A` and `\z` so there's probably A LOT of faulty regex in the wild. – MonkeyZeus Jan 06 '22 at 14:21
  • @trincot Good question. The more I think about it the more I realize I'm just soliciting any and all alternatives for `\A` and `\z`. – MonkeyZeus Jan 06 '22 at 14:24
  • @MonkeyZeus You are not making it clear. There is no `\A` and `\z` support in JS, because `^` and `$` do exactly that when `m` flag is not used. `^` matches string start and `$` matches the *very* end of string without multiline flag. Currently, the answer is just "use `^` and `$`". – Wiktor Stribiżew Jan 06 '22 at 16:56
  • @WiktorStribiżew I was hoping to use this post as a catch-all for `\A` and `\z` emulation in JS and even incorporate it into the **Anchors** section of https://stackoverflow.com/a/22944075/2191572. Using Google it is near impossible to find proper results for "JS regex start/end of string". Omitting the `m` flag and using `^` and `$` is one viable solution but if you need to match one of those anchors in the middle of the text then that method will not work. – MonkeyZeus Jan 06 '22 at 17:31
  • @WiktorStribiżew Additionally, if "There is no `\A` and `\z` support in JS, because `^` and `$` do exactly that when m flag is not used." is true then why do other flavors have `\A` and `\z` support? – MonkeyZeus Jan 06 '22 at 17:32
  • @WiktorStribiżew My [answer here](https://stackoverflow.com/a/70608182/2191572) inspired me to ask this generalized question. – MonkeyZeus Jan 06 '22 at 17:34
  • 1
    https://stackoverflow.com/a/4020821/3832970 is already answering what `\A`, `\Z` and `\z` does, and it is part of "What does this regex mean" post. Why shouldn't we close this question as a dupe of that post? All three main unambiguous anchors are explained concisely. Also, [this answer](https://stackoverflow.com/a/70608182/2191572) deals with the problem of emulating `\A` when you need to use `^` with `m` flag. – Wiktor Stribiżew Jan 06 '22 at 17:35
  • @MonkeyZeus Sure, and I do not suggest to close [that thread](https://stackoverflow.com/q/70607585), but this one. Unless you precise the question to dwell on JavaScript only and state clearly you discuss the `\A` and `\z` equivalents in JS regex when `m` flag is used. Partially, [my post](https://stackoverflow.com/a/59515368/3832970) answers it, only the very start of string is not dealt with there. – Wiktor Stribiżew Jan 06 '22 at 17:46
  • @WiktorStribiżew Sorry, my previous comment was irrelevant because I misread your comment. Anyways, I did not find your post via Google, Stack Overflow search, nor the existing [canonical question](https://stackoverflow.com/questions/22937618/reference-what-does-this-regex-mean). I'd like to propose adding my post to the canonical under **Anchors** as a dedicated Javascript entry. – MonkeyZeus Jan 06 '22 at 17:59
  • Please consider editing the post as I suggested in my comments, else, it sounds too broad and just as if you were looking for `^` and `$`. Which is not really that new and of much value. And their bahvior in JS can just be added to https://stackoverflow.com/questions/6908725/. Also, maybe [this post](https://stackoverflow.com/a/48832215/3832970) is also explaining the `$` / `\z` part. Hm, if I add `\A` part there, it may be just what you want to get here. – Wiktor Stribiżew Jan 06 '22 at 18:02
  • @WiktorStribiżew Those posts are language-specific and it's not Javascript. I'll consider editing per your comments when I have some time. – MonkeyZeus Jan 06 '22 at 18:35

2 Answers2

2

Apart from the lookarounds that you have used, you can try one of the following:

Disable the multiline modifier. InJavascript, by default, ^ matches \A and $ matches \z and use:

^|$

Demo

or

you can capture them in groups as shown below:

(^)[\s\S]*($)

Demo


  • (^) - match the start of the first line and capture it in group 1
  • [\s\S]* - greedily match 0+ occurences of any character(including newlines)
  • ($) - match the end of the last line and capture it in group 2
Gurmanjot Singh
  • 10,224
  • 2
  • 19
  • 43
  • Can you provide a case where using `(^)[\s\S]*($)` would be useful? The regex is guaranteed to return a match, and it will always be the whole input, and the capture groups will always be two empty strings. I fail to see how that brings any benefit. – trincot Jan 06 '22 at 15:07
  • *"Single-line mode causes the engine to treat the multi-line input string as a single line. Thus, `^` would match the "very-start" and `$` would match the "very-end"*: No, the `s` flag does not influence the behaviour of `^` nor `$`. This "very start and very end" behaviour is already the default in JS. – trincot Jan 06 '22 at 15:11
  • @trincot I was just thinking of possible ways in which we can match `\A` and `\z` apart from the lookarounds, You are correct about the default behavior in javascript. With or without the single-line modifier, [`^` behaves like `\A` and `$` behaves like `\z`](https://regex101.com/r/ev3Eiy/1). Will edit the answer. – Gurmanjot Singh Jan 06 '22 at 15:31
1

When you have no need of ^ and $ as line-boundaries, then these symbols act like \A and \z by default. Demo:

let results = 
`a good test with
a second line, and ending with a bad z
a third line, and a bad z
a final line, and a good z`
.match(/^a (\w+)|(\w+) z$/g);

console.log(results);

If you do need to use line-boundary detection in your regex, then you would normally use the /m modifier, and then you can use your idea of look-around.

Alternatively, you could leave out the /m modifier, and just use ^ and $ for \A and \z, but then use look-around for detecting the line boundaries:

  • start-of-line: (?<![^\n\r])
  • end-of-line: (?![^\n\r])

let results = 
`a bad test with
a good line, and ending with a good z
a third line, after a good line, and a bad z
a final line, and a bad z`
.match(/(?<![^\n\r]). good|good .(?![^\n\r])/g);

console.log(results);

For specific cases you can sometimes use other techniques. For instance, by default (so without /s) the pattern .* will capture anything until the end of the line, so you can be sure to be at a line-end after that capture.

trincot
  • 317,000
  • 35
  • 244
  • 286