0

I have a string to replace that looks like this:

{
        "_expandable": {
            "ancestors": "",
            "children": "/rest/api/content/164794022/child",
            "container": "/rest/api/space/AT",
            "descendants": "/rest/api/content/164794022/descendant",
            "history": "/rest/api/content/164794022/history",
            "metadata": "",
            "operations": "",
            "restrictions": "/rest/api/content/164794022/restriction/byOperation",
            "space": "/rest/api/space/AT",
            "version": ""
        },
        "_links": {
            "base": "https://***/confluence",
            "collection": "/rest/api/content",
            "context": "/confluence",
            "edit": "/pages/resumedraft.action?draftId=164794022&draftShareId=e44b5ec9-f1a1-463e-aa40-6667c6022ec8",
            "self": "https://***/confluence/rest/api/content/164794022",
            "tinyui": "/x/po7SCQ",
            "webui": "/display/AT/Jira+Dev"
        },
        "body": {
            "_expandable": {
                "anonymous_export_view": "",
                "editor": "",
                "export_view": "",
                "styled_view": "",
                "view": ""
            },
            "storage": {
                "_expandable": {
                    "content": "/rest/api/content/164794022"
                },
                "representation": "storage",
 **here**====>      "value": "<p class=\"auto-cursor-target\"><br /></p><ac:structured-macro ac:name=\"details\" ac:schema-version=\"1\" ac:macro-id=\"6f61e6bd-3edc-4e93-a9b7-2f15cd5fc33c\"><ac:parameter ac:name=\"id\">1</ac:parameter><ac:rich-text-body><p class=\"auto-cursor-target\"><br /></p><table class=\"wrapped\"><colgroup><col /><col /></colgroup><tbody><tr><th colspan=\"1\">Hostname</th><td colspan=\"1\">jira-dev</td></tr><tr><th>IP</th><td>192.168.182.231</td></tr><tr><th colspan=\"1\">Static/Dynamic IP?</th><td colspan=\"1\"><div class=\"content-wrapper\"><p>Static</p></div></td></tr><tr><th>Server</th><td>Hosted by IT Team</td></tr><tr><th colspan=\"1\"><p>Installed Product</p></th><td colspan=\"1\">Jira Software + Service Management</td></tr><tr><th colspan=\"1\"><p>Necessity</p></th><td colspan=\"1\"><div class=\"content-wrapper\"><p>Normal</p></div></td></tr><tr><th>OS</th><td>Ubuntu 20.04</td></tr><tr><th>Monitoring</th><td>No</td></tr><tr><th>Backup</th><td>No</td></tr><tr><th colspan=\"1\">Installed Product URL</th><td colspan=\"1\"><a href=\"http://jira-dev:8080\">http://jira-dev:8080</a></td></tr><tr><th colspan=\"1\">Using SSO</th><td colspan=\"1\">No</td></tr><tr><th colspan=\"1\">Product credentials</th><td colspan=\"1\"><div class=\"content-wrapper\"><p class=\"auto-cursor-target\"><br /></p><ac:structured-macro ac:name=\"secure\" ac:schema-version=\"1\" ac:macro-id=\"baba2872-b3b8-45e2-a5b4-fe7384f862d2\"><ac:parameter ac:name=\"title\">Product credentials</ac:parameter><ac:rich-text-body><span class=\"sec-icon-lock icon16\">&nbsp;</span><pre class=\"secret\">-----BEGIN PGP MESSAGE-----\nVersion: BCPG v1.59\n\nhQEMAxOSOe32i2V3Agf/SGkioVaXxO/pLAdaT6K7+tNBzVdCgmdYz8rIPF2C+fw9\nY8W+3++H8IyWMVDmSlAV6zENi/YnV9roOJC/ndSHEHEiBAtfHQUjT62cRQM7b3fo\nwOKhDETne4q42bFEJbfo9TJ+eYhOTJ4GduRJz1yNetgWpAbiVg3rXj7Aox9xeWIe\nHK1rGm5ZzIElXLI9VpjNvKG0aqVQS4QefcuKi6/xVnZuFkdA3IGE2yPWJizPAjyt\nlkD7iRi1Ol46b0xPDVsDfpiwQAdpwM2NmOJwbT6mRBqx0gXeKOXIUOUwDdC6biVJ\nLuau6FDgdQru+oVsXnTD2dM+M7yyhJaMtttUJch9btLCEAHlw2panHKUC6iUxbjZ\nLA8c9z3RgSq01G/gxFMvO3hSs6ih13SAdsCz18MIFdaTDU4+6cMR9hSsgF+8qxtY\nl1JEziDFpqQgZZoDv7afZn3+3IdMQ7mwQgqVu+xsckTe66hO8DlRuslyXiU39Mct\nJuUziC3OGD74x2ZhiFXxLgn4XI77TnEc5qUh6imK4xli6Pyz1Jy4RbgzdNunBN2P\n9qMxNO9fgdx5vfVxmGGaGIbvZ3a3dsSr0vi92xUmV1kd7oaUCuNe2Tw55Eb52fsA\nUQQ1WM/NZi31/cWAPyhLx8cTByMc/RjHg+h0UIlo50CBTNUOPE0QgdAXXZzZ17t5\nsvNdEBswMCHmcMIrCEGa0kWvykgK0D7kvmu+U5yzMM9482K2rws+1Q8e5UHyJ55e\nKn4cUR5yjnBXGZwerSBrIKhUcpGFPCDgctFpV6U8KxrY/lDV7k8TtsV9f71i3o51\noEvV/v9ufoWsFsp5qJRSwY/qkfYAOr8pw5mHFN3pC2MOOkkj1xDOkEwr4/J1wDaI\n8VAGONGizwDnNvYD58LpaAYnQWkdI2WEVLpkKQWgGolJSuDkmpY2wWiSxcAFI31X\nQY1e3nFzXQPcB6MkCW0P1buMUrJnQaVFQmtPf4A/yhmdK15jHfPLbUyIB1j6ewIm\njEDfo276k+nAdskmUNo+0KekJta8RHCS9tR5H4qr4LLiUOmhPYTN7MyDC+aCXX+N\nLtNpnMCQVHVxWTuCCqhmlI1VIOjUOJjAvNKX1+DAhSOquo2FXPeo0nS/MYFeRu/c\npmu5WUR5DI2kZb/psp1Lj+awRvoOy3EV5Tv9a7MfrebvjnV021+JbK2uQVViFtvg\nGAKu8dPDUW0u0jxLWeFxm/RXzcStyS2+CQQ3UY1gdqvenzZbH0PKq0vHmShy/J3b\nK4kT09FF/Wcc3j6f4pSwR1B23p9fNE17iUvcNoU9c+tD3g==\n=Qwvl\n-----END PGP MESSAGE-----\n</pre>Secured content</ac:rich-text-body></ac:structured-macro><p class=\"auto-cursor-target\"><br /></p></div></td></tr><tr><th colspan=\"1\">Host credentials</th><td colspan=\"1\"><div class=\"content-wrapper\"><p class=\"auto-cursor-target\"><br /></p><ac:structured-macro ac:name=\"secure\" ac:schema-version=\"1\" ac:macro-id=\"fbc7388c-0965-4b10-8acc-0d1233ca3ef4\"><ac:parameter ac:name=\"title\">Host credentials</ac:parameter><ac:rich-text-body><span class=\"sec-icon-lock icon16\">&nbsp;</span><pre class=\"secret\">-----BEGIN PGP MESSAGE-----\nVersion: OpenPGP.js v4.10.10\nComment: https://openpgpjs.org\n\nwcBMAxOSOe32i2V3Agf+IKFt2bSmyFl4Sk3YtTf1cXu+Xv9yZ0c/iP4RJ9ll\n5P9LM8DKPtBL+othBMLEUigNEgjXOrANp11W/endk1Ulst4UkTyttQQx5JZ2\nyNI2Q0M5uUfj/2tlCq9TTO1eXb/bffM+cKzk0D68UWC+EBvXpRp5sbKVz1Ya\nJj7nYItETTuWPUjF0uEaYVlbmsdfe3dvVy63EPw5GZdVobwv++93ZIEEhKmS\nvc+d+iw9L+Ov16kXCQaHNXzyiwtvp5nIIMYORp3IaRrbzmBqiV07RjIZrvNR\nyozEGcNWdSW7egC1k+JEF+qi2kLASglKLWFWmHn/cMpetULl8Z9c3VFZpnu7\nENLBVwFQ2f3uaF+A6t19Zi5CKptV+f1qtYekyZZok61TBkldQD4AL2UEBDB0\nMpUfEEdy4vgYqNjGWGOpX2QbWjXZDhxPAQgNr6XxxcJ7L1gzHLZT45MjFzB9\nBBhtX/qvczL1uWNHwYErUZGbwX6pwfyfbTUDX57bDbOYUG0A+nZjWIRJt5tA\nFPWiM0vicufuMACUYG00n3+C2Eu/DPIcRaHRhnz1aEDOQ4dX19ZpUCY0hWeZ\ndnhtLEYOXxTy6bgsHoBIHxac+DQ9a/0iFSNIErXfIq7yrABPEfn04Kc3tkXJ\nK+RAFQ7aJ93LjkfYMqxjLVp1lAZ05dealMLHStkvisPI3Y0qDGwPKmg9kkMD\nBnF5OuU6L/RXzei9eUHU4O2HOJtf5ClTZ7vHBXyBzoZ1JOUu2axAaOJq7Y8h\nm7L1vYJngepSMrh4xLzQXuoegM049NNSIsumioCyF4VBvtopATta1cG/U2dF\n/lahHpm0l3FtdWodNCag2Ejsr61+H5gIHinqPZC96MUmdbOOzWnHXlXjAAO/\nzkXNDAAJss+WolNuF+o8yUd9w9woYIuqzrXOOMhEM1pAxAiBhOjeXI3lQXa6\nf0pr/txZXy+qrvuQlcaF5EyWc4GrLTnuceBWAhHIrsaEhLQVf5RtJDrvgdyR\nJLw4+79Hzt+/R6gRP6Pat1bN9e734/w09gpdvnolzWxTzpn7Wuje4uX4w+M=\n=CiIl\n-----END PGP MESSAGE-----\n</pre>Secured content</ac:rich-text-body></ac:structured-macro><p class=\"auto-cursor-target\"><br /></p></div></td></tr><tr><th colspan=\"1\">Status</th><td colspan=\"1\"><div class=\"content-wrapper\"><p><ac:structured-macro ac:name=\"status\" ac:schema-version=\"1\" ac:macro-id=\"50e10a44-3a60-4c7c-aa16-8a7577487768\"><ac:parameter ac:name=\"colour\">Red</ac:parameter><ac:parameter ac:name=\"title\">PING</ac:parameter><ac:parameter ac:name=\"\" /></ac:structured-macro><span> </span><ac:structured-macro ac:name=\"status\" ac:schema-version=\"1\" ac:macro-id=\"1e1a2aa2-80ee-49e9-8f4c-5c5335ac3f52\"><ac:parameter ac:name=\"colour\">Green</ac:parameter><ac:parameter ac:name=\"title\">ssh</ac:parameter><ac:parameter ac:name=\"\" /></ac:structured-macro><span> </span><ac:structured-macro ac:name=\"status\" ac:schema-version=\"1\" ac:macro-id=\"68710b0e-2f40-4156-ac81-15f1c3c1d025\"><ac:parameter ac:name=\"colour\">Green</ac:parameter><ac:parameter ac:name=\"title\">HTTP</ac:parameter><ac:parameter ac:name=\"\" /></ac:structured-macro></p></div></td></tr></tbody></table><p class=\"auto-cursor-target\"><br /></p></ac:rich-text-body></ac:structured-macro><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p><p><br /></p>"
            }
        },
        "extensions": {
            "position": "none"
        },
        "id": "164794022",
        "status": "current",
        "title": "Jira Dev",
        "type": "page"
    }
}

i am trying to replace 3 of the properties(i will paste formatted, but they are on 1 line in the response):

<ac:parameter ac:name=\"colour\">Red</ac:parameter><ac:parameter ac:name=\"title\">ssh</ac:parameter>
<ac:parameter ac:name=\"colour\">Green</ac:parameter><ac:parameter ac:name=\"title\">http</ac:parameter>
<ac:parameter ac:name=\"colour\">Green</ac:parameter><ac:parameter ac:name=\"title\">ping</ac:parameter>

I am targeting the first one with:

    - name: replace value in body
      set_fact:
        page: "{{ page.json | regex_replace('\"colour\">(.{1,5}?)<\/ac:parameter><ac:parameter ac:name=\"title\">ssh<\/ac:parameter>', '//1') }}"

this is resulting in <ac:parameter ac:name=//1<ac:parameter ac:name=\"\" /> and the word I need to match is in capture group 1. How to make the replacement properly? I need to replace Red with a variable I have: actual_statuses[0] (0 index of list of statuses I obtain beforehand, actual value 'Green')

2
  • 2
    Two things: 1. you are confusing the \1 backreference syntax with //1 that you made up 2. it appears you are trying to manipulate xml in json as if it were a string, which is the road to ruin. If nothing else, you'll have an easier debug time if you set_fact: { the_xml: "{{ (page.json|from_json).body.storage.value }}" } and then manipulate it from there Commented Sep 17, 2021 at 15:41
  • i would but the XML is invalid and i cant parse it. I have separate (dead) thread for that. This is why i work with the string representation. (also, it is html page, not xml). About the first, yes I am aware, this is why i post the question. I do not how to work with both reference and replacement. Commented Sep 20, 2021 at 21:24

1 Answer 1

1

It's hard to tell from your question whether that cited JSON is how ansible sees it, or you copied that from somewhere else and just assumed that is how ansible sees it

Either way, as best I can tell you're interested in inserting actual_values[0] into the place of the capture group in your regex, which isn't how that process works. In your case, you actually want everything except the capture group carried over, which means you don't care about the capture group's value, which means you shouldn't use a capture group

You also have an unusual .{1,5}? syntax which I'm guessing you mean as "either nothing, or a string of 1 to 5 characters," which in regex is expressed as .{0,5}

For your first problem, you'll want to ensure you and ansible are working with the same understanding about that data; that's what the | type_debug filter is for, since - debug: var=page.json can be misleading with all the jinja2 and stdout callback plugins that touch that data on the way back to your terminal.

Next, and this is kind of related to that, you'll want to know if some process in ansible that has touched that data has introduced escape characters in front of those " in your body.storage.value; my code snipped below works on the assumption they are not present, because your snippet assumed they were not present, but you'll want to verify that for sure. You don't have to leave that assert: in your final playbook, but it can help you ensure you're starting from the right place because if the regex_replace doesn't find any matches, it merely doesn't do anything, which can make it seem like it is silently failing. We want loud failures.

Finally, getting to the part you care about: your process is that you have a bunch of literal text, a variable part, and a bunch of literal text. While it might not be necessary, it is clearest to send that literal text through | regex_escape to let the computer do any regex quoting for you. Then, using that same literal text, tell regex_replace to swap out the variable part with the new bookends

    # <JUST FOR YOUR DEBUGGING>
    - debug:
        msg: It seems the type of page.json is {{ page.json | type_debug }}
    - assert:
        that:
        - 0 != (page.json | regex_findall('<ac:parameter ac:name="colour">') | length)
    # </JUST FOR YOUR DEBUGGING>

    - set_fact:
        page: >-
          {{ page.json | regex_replace(
            (head | regex_escape) + ".{0,5}" + (tail | regex_escape),
            head + actual_statuses[0] + tail) }}
      vars:
        head: '<ac:parameter ac:name="colour">'
        tail: '</ac:parameter><ac:parameter ac:name="title">ssh</ac:parameter>'
        actual_statuses:
        - Alpha
        - Beta
        - Charlie

produces:

...><ac:parameter ac:name="colour">Alpha</ac:parameter><ac:parameter ac:name="title">ssh<...

which is what I think you wanted

Sign up to request clarification or add additional context in comments.

1 Comment

This did the trick. priceless help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.