# Perl / Java / PCRE, 39 bytes

	^((((\3|^x)xx)*)x?+)(?=(\1*)\2+$)\1*$\5

[Try it online!](https://tio.run/##RU7LasMwEPyVJYhYG9tYdvElsmIH0mtPvdWJSEMMAjVxJRdUVPfXXcUNZA/LzOxjpj8bXU4f30AMB6@vp6MGkvFARbXbvm43I3RXQ4kVjFcbjh5UFxj63qjLAIv2suAjNFrYXquBRmmU2K93O4QTmaR5kuP587ZUP1QWdFwTifz2ywbHo2l0VaBv9Fu@F6GzPb/7qjslqhLzOKA4Rq86oDRyETgIS4ggfiEjJkNP7HI5h5uzheA5/89KFB/HUcrnl52U04GGap9@Dg6dwxW6OkZaC9rmK2yLmGAApC2niaVFydgf "Perl 5 – Try It Online") - Perl  
[Try it online!](https://tio.run/##bVLvT9swEP3OX3GLmGq3xaRMfJmJ0DZt0iTYJvjYFslNnNbgXDLboQHG396d0@wHEv5i393zO7/nu1X36ui2uNuZqqldgFuKhanFWML/mTYY@2rO6bXuqHLQtCtrcsit8h4ulUF4giHngwq03demgIoq7Do4g2tQbu3nSw5h4@qth89drptgarp5APDFWA1lhnrbH1ki8rrQguoJlx/bstROF1daFdrBqoe9TLI/N4ew5FwOff00yO0m8jPmsxVpUMWFQc04f5Nhay03JfNC/2yV9Sw5Ho/HCedPL6F7BsbCqwRPxBD@MhDBMTGsCHcn/SQbLXAU9yCf97nnHyoE7RBcNpxIbdXEBp5LcmNV11YrhMesJEYt4TpXiCTdYNMGyCCqHXLs@sEHXQmDXMKgs4eJjfLfdBfomb3FAIMhlt5OHHsQEmKQONTnS7BUjijhG2sCS47oEwgfAFOqfMVAY@BEo5zXFDA7T5d8Cjh7tSisxnXYnJ3AOUQkvKdttiTGfKPcfNkNevoIZ0sJH5xTD16UxlrWTUfdqDcFoKxd1EbPyDCVgGcZzmibTEjgpQr5hhyqiM2Jah@xfnKRBvwTke8nRmydatjQIq@bh@/llcK1pk7pFDmPSktgFbXHgryLf/vIB5NrcmzrTNAsfiqXj1lwbfyff@WGPAwlS976hCzh8jmugzhVuxtGa/Hu103Hu46PeXc@4ew8Y4vZmC9OJoecDoeL010coF16dHKapr8B "Java (JDK) – Try It Online") - Java  
[Try it online!](https://tio.run/##nVJLb9swDL77VxCCAIuJHT@abkhlN5e2QIBhh3W3uhUcR6mNOrIhK4CBLL89o4P1smN5IPj6@FEUt@VQXzZPzzlYXe4gtDvwfbBZ5qsvie9l677ugVvIgUUMFtBb/a6s7tuy0sKPFrO1UnXZOlV1h75ptS1EgbL4FQ1@QOQB7Cmo3vVUYJw2bhBKPW1@PCqFASRILamx9BrTqEE7wfrK6sW2rD6cJaXa5tA4FgBbpqvl6tv3dHXLUHr7zgre5LHkbb6n7oN4/v2w@YkST9DsBW9fBmdbbcjCMHnNc1YYhlQ8HLeUoXAQB2GCE16PfdvttGAhC6hcEr7qjsZN2Cwl0As1IB2/Sg/gymz@@dxk@TVP1nyORA3iuqFD6apacBsQ2bQuXTrhj37ADSLCaRqxQV3V3TSXBHpKImHygRt5Jprzf2sVKC9vgqS4@fM24jjiDMf1HMU6F0UywyKdcySDF7eXr322d6UPDTB@snd3YXJm9xXtZUEXIPWoK4iOg422jYmmm/hMXeJwmcbxXw "Bash – Try It Online") - PCRE1  
[Try it online!](https://tio.run/##XVDfa4MwEH7vXxFCwFzVVl27UVLpyzYojD1se6ttsC5WmY0hpiB0@9vdWfa0wB336/u@y5nKDOuNqQxhlqSEzimZEWPVSVplmrxQ3JvPphspq7xxsmjPpm6UzXgGInubd15APLQSi/KkxgHtlHYdl/J5@/IkJQQkBqREYjGpdS075Tg1hVWzY158OYtONvW5djQgdJGsFqv7h2S1pCAmZWs5q9NIsCYtkb3j7x@P21cQcCV1yVmz65xtlMYIwnifpjTTFHC4uxyxg@UgCsIYRrzqTdN@Kk5DGuC4QHzRXrQbsesEQTskQB/txYSQm7L@y5lep7c@Rr4PKE347ULn3BUVZzZAsfFcKnfc672AaQAg13HFGlRRteNeguBXYkHGnDAtflDm599ZOYjhwPFld9@HHvoeptBvfOCblGfxFLLEZ4ABy5bDEIWLJIp@AQ "PHP – Try It Online") / [Attempt This Online!](https://ato.pxeger.com/run?1=XVDdSsMwFMbbPUUIgeZs7dbWTR1Z6Y0KA_FCvVs11JraYpeWNIOC-ga-gTeC6Dvp03i67cpATs7P953v5Lx_NkXz8XvwtojRIcyQiNAJJWPSGPUojWqqNFPcmYyHsZRFWlmZ1eumrJRJeAIiuZq0jkscvDkm5aPqAdoqbVsu5fny4kxKcEkA2BIbi0GpS9kqy2mTGTW-T7Mna9DIqlyXlrqETsP5dH50HM5nFMQgrw1nZeQLVkU5dm_59c3p8hIEPJMy56xatdZUSqMHXnAbRTTRFBDcbu6xgmnXd70Aer7qmqp-UJx61EW4QH5Wb7TtuYsQSStsgNa_FQNCtsp6HzO9iLZ19EYjQGnCtxtapzYrODMuivXrUqnlTue4TAMAee5HLEFlRd3PJQh-JRCkjwnT4hVlXv-tlYP42tjcO_lx7jie5PDlroOugyF08Qh4HPEkGEISjhigw5LZDv6xf759bxr6_i76Aw "PHP - Attempt This Online") - PCRE2  

This is the same as the 40 byte regex below, but drops .NET support by using a possessive quantifier, `x?+` instead of `|^$`, to match \$0^4\$. This works because `x?+` will always consume 1 `x` if it can, and will only consume 0 `x`s if \$\it\text{tail}=0\$, which can happen in two ways:
 - If the input was \$0\$, in which case `\1` and `\2` will have both captured \$0\$, and the second half of the regex will match.
 - If the input was nonzero, in which case `\2` will have captured the entire nonzero input value, making it impossible for the second half of the regex to match, as `\2+` won't be able to match with \$\it\text{tail}=0\$.

It matches [primo's solution](https://codegolf.stackexchange.com/a/22084/17216) in length and list of supported regex engines, except that .NET is not supported.

# <sub><sup>Perl / Java / PCRE</sup></sub> / .NET, <s>42</s> 40 bytes

	^((((\3|^x)xx)*)x)(?=(\1*)\2+$)\1*$\5|^$

[Try it online!](https://tio.run/##RU7LasMwEPyVJYhYG9tYdvGlshIH0mtPvVWJSEsMAjVxJRdUVPfXXcUNZA/LzOxjpj9ZU08f30Ash2Au70cDpOCRima3fdmuR@gulhInGG/WHAPoLjIMvdXnARbyvOAjtEa43uiBJnmSua83N8QTleVlVuLp87q0uass6vhIFPLrLxcdj7Y1TYWhNa/lXsTO9vzmq2@U6EbM44jSFIPugNLEJ@AhLiGC@IWC2AIDccvlHG7OFoOX/D8r0XwcR6WenndKTQcaSz78HDx6jyv0SDeCynKFskoJRkBkPU0sr2rG/gA "Perl 5 – Try It Online") - Perl  
[Try it online!](https://tio.run/##bVLLbtswELznK7ZCCpO2w8gpcikjBG3RAgWatkiOtgPQEmUzoVYqScXK69vdpaw@AoQXcneHs5zh3qg7dXRT3O5M1dQuwA3FwtRiLOH/TBuMfTXn9Fp3VDlo2pU1OeRWeQ8XyiA8wpDzQQXa7mpTQEUVdhWcwTUot/bzJYewcfXWw@cu100wNd08APhirIYyQ73tjywReV1oQfWEy49tWWqni0utCu1g1cNeJtmfm0NYci6Hvn4a5HYT@Rnz2Yo0qOKbQc04f5Nhay03JfNC/2qV9Sw5Ho/HCeePL6F7BsbCqwSPxBD@MhDBMTGsCHcr/SQbLXAU9yCf97nnnyoE7RBcNpxIbdXEBp5LcmNV11YrhIesJEYt4SpXiCTdYNMGyCCqHXLs6t4HXQmDXMKgs4eJjfLfdRfomb3FAIMhlt5OHHsQEmKQONTnS7BUjijhG2sCS47oEwgfAFOqfMVAY@BEo5zXFDA7T5d8Cjh7tSisxnXYnJ3AOUQkvKdttiTGfKPcfNkNevoIZ0sJH5xT916UxlrWTUfdqDcFoKxd1EbPyDCVgGcZzmibTEjghQr5hhyqiM2Jah@xfnKRBvwTke8nRmydatjQIq@b@x/lpcK1pk7pFDmPSktgFbXHgryLf/vAB5NrcmzrTNAsfiqXD1lwbfyff@WGPAwlS976hCzh8jmugzhVu2tGa/Hu6brjXcfHvOPsPGOL2ZgvTiaHnA6Hi9On68NdnKBdenRymqa/AQ "Java (JDK) – Try It Online") - Java  
[Try it online!](https://tio.run/##nVJLb9swDL77VxCCAIuJHT@abkhlL5etQIBhh3W3uhEcR6mNObIhK4CBNL89pYP1smN5IPj6@FEUd@VQXzePTzlYXe4htHvwfbBZ5qtPie9l677ugVvIgUUMFtBb/aqs7tuy0sKPFrO1UnXZOlV1x75ptS1EgbL4HQ1@QOQBHCioXvVUYJw2bhBKPW5@/lAKA0iQWlJj6TWmUYN2gvWV1YtdWf11lpRqm2PjWABsma6Wqy9f09U9Q@kdOit4k8eSt/mBug/i6c/3zS@UeIbmIHj7PDjbakMWhslLnrPCMKTi4bSjDIWDOAgTnPB67NturwULWUDlkvBVdzJuwmYpgZ6pAen4RXoAN2bzz@cmy295suZzJGoQtw0dS1fVgtuAyKZ16dIJf/QDbhARztOIDeqq7qa5JNBTEgmTD9zIC9Fc/lurQHndCpLi7m074jjiDEcU61wUyQyLdM6RDF7cv2359XO/7d34QwOMn@3DQ5hc2LeKFrOgE5B61BVEp8FGu8ZE01F8pK5xuEzj@B0 "Bash – Try It Online") - PCRE1  
[Try it online!](https://tio.run/##XVDfa8IwEH73rwgh0Jy22na6IbH4sg2EsYdtb1ZD7VJbVtOQRiiof3t3lT0tcMf9@r7vcqY0/WptSkOYJQmhM0qmxFh1lFaZOssV92bT8VrKMqudzJuTqWplU56CSD9mrecTD63AojyqYUA7pV3LpXzdvL1ICT6JACmRWIwqXclWOU5NbtX0kOU/zqKTdXWqHPUJncfL@fLxKV4uKIhR0VjOqiQUrE4KZG/559fz5h0EXEhVcFZvW2drpTGCINolCU01BRxuzwfsYNkP/SCCAa86UzffitOA@jguEJ83Z@0G7CpG0BYJ0Ic7MSLkrqz/cqZXyb2P0WQCKE34/UKnzOUlZ9ZHseFcKnPc6zyfaQAgl2HFClReNsNeguBXIkGGnDAtbihz@3dWDqLfc3zpw3XfQdfBGDrg64Sn0RjSeMIAA5YurnvW92Ewj8PwFw "PHP – Try It Online") / [Attempt This Online!](https://ato.pxeger.com/run?1=XVDdSsMwFMbbPUUIgeZs7dbWTR1Z2Y0Kgnih3q0u1Jq6YJeWNIOC-ga-gTeC6Dvp03i67cpATs7P953v5Lx_1qv64_fgbTZHhzBLEkJHlAxJbdWjtKous1xxbzTsz6VcZaWTebWudalsylMQ6fWo8Xzi4S0wKR9VBzBOGddwKc8vLs-kBJ9EgC2xsehpo2WjHKd1btXwPsufnEUjS73WjvqEjuPpeHp0HE8nFESvqCxnOgkFK5MCuzf85vb04goEPBNdcFYuGmdLZdCDILpLEpoaCghuNvdYwbQf-kEEHV-1dVk9KE4D6iNcID-vNsZ13FmMpAU2QBveiR4hW2Wzj5mZJds6eoMBoDTh2w2tM5evOLM-inXrUpnjXuv5zAAAee5G1KDyVdXNJQh-JRKkiwkz4hVlXv-tlYP42rgiOPnhS44nPXxZttC20IcW-DzhadSHNB4wQIelk5cl2-E_9s93GIzjMNxFfw "PHP - Attempt This Online") - PCRE2  
[Try it online!](https://tio.run/##RY/daoNAEIVfRWTAXe0GteQmsiSQ6z6BPyB2Ehe2s7JucInx2a22lM7V@Q6Hw5zBTGjHHrVewcrS4h19fToRTuwSrQ3brnp/NZ57z2PuOTtLVmUxr/IE@CagOr4aWKPLW3g1X4PS@BnyAp4yLW7GYtv1DHSgKABFw8PxGVoJWoyDVi4UYaFuDNpDZx7khHZBvgcSCW2Z1stWwIBkqcjVP04BJDT@cbZzkvB577CHj9Z1PY4s8lEMxH/tJ58nqxyK3oxu2d7Kin8OBJltqFaEAdCyLGsq8mOafgM "PowerShell – Try It Online") - .NET


This uses the equivalent of `^(\1xx|^x)*$` to match a perfect square using a nested backreference (made more complicated by needing to capture that square minus \$1\$), and then uses a square-testing algorithm which works thanks to the Chinese remainder theorem (which only requires ECMAScript or better, and is the reason for needing to capture the square minus \$1\$), to assert that the captured perfect square is the square root of the inputted number. The latter algorithm is [explained in this post](https://codegolf.stackexchange.com/questions/179239/find-a-rocco-number/179420#179420), and this exact square-testing regex is used [in the second answer in this post](https://codegolf.stackexchange.com/questions/144561/golf-the-pseudoprimes/179024#179024).

If it did not need to match \$0^4\$, the regex would be <s>39</s> **37 bytes**, beating [primo's excellent solution](https://codegolf.stackexchange.com/a/22084/17216).

```
    ^                    # tail = N = input number
    (                    # \1 = the largest perfect square for which the
                         #      subsequent expression matches; tail -= \1
        (                # \2 = \1 - 1
            (            # \3 = nested backreference
                # On the first iteration,   \3 =  1 + 2 = 3;
                # on subsequent iterations, \3 = \3 + 2
                (\3|^x)
                xx
            )*           # iterate \3 any number of times (may be zero); \2
                         # becomes the total of all these iterations
        )
        x                # \1 = \2 + 1
    )
    # Assert that N == \1^2
    (?=
        (\1*)\2+$        # iff \1*\1 == N, the first match here must capture \5=0
    )
    \1*$\5               # assert \1 divides N-\1, and \5==0
|
    ^$                   # Allow us to match N=0, which can't be matched above
```