replaceRE: Regex loop issues with regex tested on regex101

I am working on a content transformer (another one) for my hugo template.

I was building the transformer using regex101.com. That awesome site to work with regexp.

This is the regex I am working on: regex101: build, test, and debug regex

I am using this code in the transformer on the content partial

{{ $content = replaceRE $content "(?s)\x60\x60\x60ad-([^\n]*)\ntitle:([^\n]*)\n([^\x60]*)\x60\x60\x60" "{{% ad $1 \"$2\" %}}$3 {{% /ad %}}" }}

The error it is reporting is below. It’s strange that I’ve been able to use raw Go regex using the code generator just joining all the lines into one and using \n instead of linebreaks.

Start building sites … 
hugo v0.85.0+extended linux/amd64 BuildDate=unknown
ERROR 2021/07/29 15:03:12 render of "page" failed: execute of template failed: template: _default/single.html:163:11: executing "_default/single.html" at <partialCached "content.html" . .Permalink>: error calling partialCached: "/home/lucasew/WORKSPACE/zettel-hugo/themes/kb/layouts/partials/content.html:39:14": execute of template failed: template: partials/content.html:39:14: executing "partials/content.html" at <replaceRE $content "(?s)\x60\x60\x60ad-([^\n]*)\ntitle:([^\n]*)\n([^\x60]*)\x60\x60\x60" "{{% ad $1 \"$2\" %}}$3 {{% /ad %}}">: error calling replaceRE: error parsing regexp: invalid nested repetition operator: `++`
ERROR 2021/07/29 15:03:12 render of "page" failed: execute of template failed: template: _default/single.html:163:11: executing "_default/single.html" at <partialCached "content.html" . .Permalink>: error calling partialCached: "/home/lucasew/WORKSPACE/zettel-hugo/themes/kb/layouts/partials/content.html:39:14": execute of template failed: template: partials/content.html:39:14: executing "partials/content.html" at <replaceRE $content "(?s)\x60\x60\x60ad-([^\n]*)\ntitle:([^\n]*)\n([^\x60]*)\x60\x60\x60" "{{% ad $1 \"$2\" %}}$3 {{% /ad %}}">: error calling replaceRE: error parsing regexp: invalid escape sequence: `\e`
ERROR 2021/07/29 15:03:12 render of "page" failed: execute of template failed: template: _default/single.html:163:11: executing "_default/single.html" at <partialCached "content.html" . .Permalink>: error calling partialCached: "/home/lucasew/WORKSPACE/zettel-hugo/themes/kb/layouts/partials/content.html:39:14": execute of template failed: template: partials/content.html:39:14: executing "partials/content.html" at <replaceRE $content "(?s)\x60\x60\x60ad-([^\n]*)\ntitle:([^\n]*)\n([^\x60]*)\x60\x60\x60" "{{% ad $1 \"$2\" %}}$3 {{% /ad %}}">: error calling replaceRE: error parsing regexp: invalid escape sequence: `\e`
ERROR 2021/07/29 15:03:12 render of "page" failed: execute of template failed: template: _default/single.html:163:11: executing "_default/single.html" at <partialCached "content.html" . .Permalink>: error calling partialCached: "/home/lucasew/WORKSPACE/zettel-hugo/themes/kb/layouts/partials/content.html:39:14": execute of template failed: template: partials/content.html:39:14: executing "partials/content.html" at <replaceRE $content "(?s)\x60\x60\x60ad-([^\n]*)\ntitle:([^\n]*)\n([^\x60]*)\x60\x60\x60" "{{% ad $1 \"$2\" %}}$3 {{% /ad %}}">: error calling replaceRE: error parsing regexp: invalid escape sequence: `\e`
Error: Error building site: failed to render pages: render of "page" failed: execute of template failed: template: _default/single.html:163:11: executing "_default/single.html" at <partialCached "content.html" . .Permalink>: error calling partialCached: "/home/lucasew/WORKSPACE/zettel-hugo/themes/kb/layouts/partials/content.html:39:14": execute of template failed: template: partials/content.html:39:14: executing "partials/content.html" at <replaceRE $content "(?s)\x60\x60\x60ad-([^\n]*)\ntitle:([^\n]*)\n([^\x60]*)\x60\x60\x60" "{{% ad $1 \"$2\" %}}$3 {{% /ad %}}">: error calling replaceRE: error parsing regexp: invalid nested repetition operator: `**`
Built in 9249 ms

It seems to detect some kind of loop that is under control here because I setup to match all characters except one that is the stop criteria.

  1. The arguments to replaceRE are in the wrong sequence.

    replaceRE PATTERN REPLACEMENT INPUT [LIMIT]

  2. The regex patterns are easier to create and understand when written as string literals (surround pattern with backticks instead of quotation marks).

  3. You can simplify your pattern like this:

    `(?s)\x60{3}ad-(.+)\ntitle:\s*(.+?)\n(.+)\x60{3}`
    
1 Like

In addition to @jmooring‘s remarks: searching for ([\n]*) is a bad idea: this matches zero to any number of newlines, you use that pattern (match something zero to any number of times). Which means that you can end up with empty groups in your replacement.

Regex101 only tells you if a RE is statically syntactically ok and matches your test string.

In my pattern I did like match everything except a symbol to stop when some symbol is found. Like [^\n]* to match the rest of the line. Regex 101 and golang’s stock regex engine supported that just fine.

You need to fix this.

Now I realised why it’s not working

The problem is that code block is already parsed as a code element. I will need to change the regex. BTW thank you. That detail I really missed.

I’ve had issues about that replace can’t render the markdown code inside
The code has a workaround to circumvent this. When Hugo get the support to replace groups processing I can do this in a better, and probably faster, way


{{ $content = replaceRE  `(?s)<pre><code class="language-ad-([a-z]*)[^>]*>title:([^\n]*)\n(.*)<\/code>` (partial "admonition.html" (dict "body" (safeHTML "<markdownme>$3</markdownme>") "type" "$1" "title" "$2")) $content }}

{{ $extraBlocks := findRE "(?s)<markdownme>.*</markdownme>" $content }}
{{ range $extraBlocks }}
{{ $body := replaceRE "(?s)<markdownme>(.*)</markdownme>" "$1" . }}
{{ $content = replace $content . ($body | markdownify) 1 }}
{{ end }}

It works :man_shrugging:

Thank you everyone

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.