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.
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"
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
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.
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"
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