Ansible regex_search fails when I try to use a group with error 'NoneType' object has not attribute 'group'

Question:

I have a number of user public keys, obtained via rest call made with the URI module, and I want to pull out the uid contained within that key. Here is the relevant line of my role

- name: find users UID within key
  debug: 
    msg: uid is "{{ item.content | regex_search( 'unixid=(d+)', '\1') }}"

this fails with the error:

'NoneType' object has no attribute 'group'

If I use -vvv on ansible I find that it’s failing on this line

file "/usr/lib/python3.6/site-package/ansible/plugins/filter/core.py", line 156, in regex_search
  match = int(re.match(r'\(d+)', arg).group(1))

By comparison if I do the same regex without the group search the command works fine, other then returning more then the id I want.

I was able to get the desired functionality by chaining two regex_search commands together, but it’s ugly. I’d rather know why groups aren’t working for regex_search.

Asked By: dsollen

||

Answers:

regex_search is meant to return you the matches of the regex, not the groups, or at least in the current version of Ansible (although there are signs that it should work on the latest version?).

You can work around this using regex_findall instead, but you’ll have to add a first filter to deal with the list created:

Given the task:

- debug: 
    msg: >-
      uid is {{ 
        item.content | regex_findall('unixid=(d+)', '\1') | first 
      }}
  vars:
    item:
      content: 000 foo unixid=123 bar 987

This yields the recap:

ok: [localhost] => 
  msg: uid is "123"
Answered By: β.εηοιτ.βε

I ran into a similar problem when following ansible’s regex examples. The problem seems related to escaping backslashes. I found two ways to solve this issue using the latest version of ansible:

The first one requires only the removal of one in your code:

- hosts: localhost
  gather_facts: no

  tasks:
    - vars:
        item:
          content: some text unixid=123 more text
      debug:
        msg: uid is "{{ item.content | regex_search('unixid=(d+)', '1') | first}}"

The second approach leads to a few more changes:

- hosts: localhost
  gather_facts: no

  tasks:
    - vars:
        item:
          content: some text unixid=123 more text
      debug:
        msg: "uid is "{{ item.content | regex_search('unixid=(\d+)', '\1') | first}}""

Both result in the same (desired) output:

PLAY [localhost] *************************************************************************************************

TASK [debug] *****************************************************************************************************
ok: [localhost] => {
    "msg": "uid is "123""
}

PLAY RECAP *******************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
Answered By: a-ts
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.