# How can I match \`\\s\` or \`\\t\` in a \`search\` test?

**URL:** <https://forum.ansible.com/t/how-can-i-match-s-or-t-in-a-search-test/36755>\
**Category:** Ansible Project\
**Created:** [June 20, 2022, 9:36am UTC](https://forum.ansible.com/t/how-can-i-match-s-or-t-in-a-search-test/36755 "2022-06-20T09:36:37Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nick\_Kakouros](https://avatars.discourse-cdn.com/v4/letter/n/d26b3c/32.png) [@Nick\_Kakouros](https://forum.ansible.com/u/Nick_Kakouros)\
**Post date:** [June 20, 2022, 9:36am UTC](https://forum.ansible.com/t/how-can-i-match-s-or-t-in-a-search-test/36755/1 "2022-06-20T09:36:37Z")

</div>

Here is an example:

- hosts: localhost  
gather\_facts: false  
vars:  
q:
- ‘abc’
- 123  
tasks:
- debug:  
msg: \>-  
{{ q is search(‘abc\t’) }}

This returns false. I have tried different variations of the regex, but nothing worked. Is this possible to do?

---

<div class="post-metadata">

**Author:** ![dnmvisser](https://avatars.discourse-cdn.com/v4/letter/d/8e8cbc/32.png) [@dnmvisser](https://forum.ansible.com/u/dnmvisser)\
**Post date:** [June 20, 2022, 11:52am UTC](https://forum.ansible.com/t/how-can-i-match-s-or-t-in-a-search-test/36755/2 "2022-06-20T11:52:31Z")

</div>

Escape the tab with another single quote, like this:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{ q is search('abc\\t') }}

Dick

---

<div class="post-metadata">

**Author:** ![dnmvisser](https://avatars.discourse-cdn.com/v4/letter/d/8e8cbc/32.png) [@dnmvisser](https://forum.ansible.com/u/dnmvisser)\
**Post date:** [June 20, 2022, 11:53am UTC](https://forum.ansible.com/t/how-can-i-match-s-or-t-in-a-search-test/36755/3 "2022-06-20T11:53:36Z")

</div>

On 2022-06-20 (Mon) 13:52, Dick Visser w

> Escape the tab with another single quote, like this:

I meant with another backslash obviously

---

<div class="post-metadata">

**Author:** ![vbotka](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/vbotka/32/359_2.png) [@vbotka](https://forum.ansible.com/u/vbotka)\
**Post date:** [June 20, 2022, 7:22pm UTC](https://forum.ansible.com/t/how-can-i-match-s-or-t-in-a-search-test/36755/4 "2022-06-20T19:22:15Z")

</div>

> &nbsp;&nbsp;&nbsp;&nbsp;q:  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- 'abc\<tab character here\>'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- 123
> 
> &nbsp;&nbsp;&nbsp;&nbsp;- debug:  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg: \>-  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{ q is search('abc\t') }}

There are more aspects to this question:

\* It's necessary to understand the difference between 'Double-Quoted  
&nbsp;&nbsp;Style' and 'Single-Quoted Style'. See  
[https://yaml.org/spec/1.2.2/#731-double-quoted-style](https://yaml.org/spec/1.2.2/#731-double-quoted-style)  
[https://yaml.org/spec/1.2.2/#732-single-quoted-style](https://yaml.org/spec/1.2.2/#732-single-quoted-style)

In 'Single-Quoted Style' only "'" has to be escaped. As a result, the  
string 'abc\t' doesn't include TAB. It's a sequence of characters: a,  
b, c, \, t. Test it. The task below

&nbsp;&nbsp;&nbsp;&nbsp;- copy:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dest: /tmp/test.txt  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;content: |  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{ ql.0 }}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{ ql.1 }}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vars:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ql:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- 'abc\tx'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- 123

gives

&nbsp;&nbsp;\> cat /tmp/test.txt  
&nbsp;&nbsp;abc\tx  
&nbsp;&nbsp;123

The string will include TAB if you use 'Double-Quoted Style'

&nbsp;&nbsp;&nbsp;&nbsp;- copy:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dest: /tmp/test.txt  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;content: |  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{ ql.0 }}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{ ql.1 }}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vars:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ql:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- "abc\tx"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- 123

gives

&nbsp;&nbsp;\> cat /tmp/test.txt  
&nbsp;&nbsp;abc x  
&nbsp;&nbsp;123

\* The \*search\* test doesn't work with lists. It works with strings.  
&nbsp;&nbsp;See  
[https://docs.ansible.com/ansible/latest/user\_guide/playbooks\_tests.html#testing-strings](https://docs.ansible.com/ansible/latest/user_guide/playbooks_tests.html#testing-strings)

Use it to test a single item of a list. For example,

&nbsp;&nbsp;&nbsp;&nbsp;- debug:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg: "{{ ql.0 is search(regex) }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vars:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;regex: 'abc\tx'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ql:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- "abc\tx"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- 123

gives

&nbsp;&nbsp;msg: true

Also the task below, with single-quoted \*item\* and escaped backslash  
in \*regex\*, gives the same result

&nbsp;&nbsp;&nbsp;&nbsp;- debug:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg: "{{ ql.0 is search(regex) }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vars:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;regex: 'abc\\tx'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ql:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- 'abc\tx'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- 123

\* Instead, you can "Test if a list contains a value". See  
[https://docs.ansible.com/ansible/latest/user\_guide/playbooks\_tests.html#testing-if-a-list-contains-a-value](https://docs.ansible.com/ansible/latest/user_guide/playbooks_tests.html#testing-if-a-list-contains-a-value)

For example, both tasks below returns \*True\*

&nbsp;&nbsp;&nbsp;&nbsp;- debug:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg: "{{ item in ql }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vars:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item: 'abc\tx'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ql:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- 'abc\tx'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- 123

&nbsp;&nbsp;&nbsp;&nbsp;- debug:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg: "{{ item in ql }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vars:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;item: "abc\tx"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ql:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- "abc\tx"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- 123

\* If you want to use \*regex\* to test an item in a list use \*select\*.  
&nbsp;&nbsp;For example,

&nbsp;&nbsp;&nbsp;&nbsp;- debug:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg: "{{ ql|select('search', regex) }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vars:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;regex: 'abc\\tx'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ql:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- 'abc\tx'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- 123

gives

&nbsp;&nbsp;msg:  
&nbsp;&nbsp;&nbsp;&nbsp;- abc\tx

, or use it in a condition. For example,

&nbsp;&nbsp;&nbsp;&nbsp;- debug:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg: "Regex {{ regex }} is present in the list."  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when: ql|select('search', regex)|length \> 0  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vars:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;regex: 'abc\\tx'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ql:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- 'abc\tx'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- 123

gives

&nbsp;&nbsp;msg: Regex abc\\tx is present in the list.

---

<div class="post-metadata">

**Author:** ![Nick\_Kakouros](https://avatars.discourse-cdn.com/v4/letter/n/d26b3c/32.png) [@Nick\_Kakouros](https://forum.ansible.com/u/Nick_Kakouros)\
**Post date:** [June 20, 2022, 8:58pm UTC](https://forum.ansible.com/t/how-can-i-match-s-or-t-in-a-search-test/36755/5 "2022-06-20T20:58:42Z")

</div>

Thank you for your replies. The search test does work with lists and this is where the  
issue lies. Your examples helped me clear this up. The search, regex, etc tests will

convert the object to a string. In python code, this means that the list will be turned  
into a string with str(list\_here). This will escape tab characters in the list items, so

that a list [“a”, “b\t”] will get converted to the string, ‘[“a”, “b\t”]’. To match this correctly  
with the search test, I need to search for …b\t… in single quotes.

---

<div class="post-metadata">

**Author:** ![Nick\_Kakouros](https://avatars.discourse-cdn.com/v4/letter/n/d26b3c/32.png) [@Nick\_Kakouros](https://forum.ansible.com/u/Nick_Kakouros)\
**Post date:** [June 20, 2022, 9:09pm UTC](https://forum.ansible.com/t/how-can-i-match-s-or-t-in-a-search-test/36755/6 "2022-06-20T21:09:15Z")

</div>

There is also the case that the search test appears in an assert:

- assert:  
that:
- q is search(‘abc\t’)

The tab character needs to be double escaped here because (I think)  
the assert clause is interpreted as a double quoted string.

---

<div class="post-metadata">

**Author:** ![Nick\_Kakouros](https://avatars.discourse-cdn.com/v4/letter/n/d26b3c/32.png) [@Nick\_Kakouros](https://forum.ansible.com/u/Nick_Kakouros)\
**Post date:** [June 20, 2022, 9:10pm UTC](https://forum.ansible.com/t/how-can-i-match-s-or-t-in-a-search-test/36755/7 "2022-06-20T21:10:35Z")

</div>

Correction:

- assert:  
that:

- q is search(‘abc\t’ | regex\_escape)

using regex\_escape to avoid escaping manually the backslashes (‘abc\\t’)

---

<div class="post-metadata">

**Author:** ![vbotka](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/vbotka/32/359_2.png) [@vbotka](https://forum.ansible.com/u/vbotka)\
**Post date:** [June 21, 2022, 3:53am UTC](https://forum.ansible.com/t/how-can-i-match-s-or-t-in-a-search-test/36755/8 "2022-06-21T03:53:43Z")

</div>

I see. You're right. It's worth to test the escaping. The simplest  
case is when the items are double-quoted and \*regex\* is variable

&nbsp;&nbsp;&nbsp;&nbsp;- debug:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg: "{{ \_list is search(regex) }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vars:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\_list: ["a", "b\t"]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;regex: 'b\\t'

Additional escaping, because of the outside double-quotes, is needed  
when \*regex\* is value

&nbsp;&nbsp;&nbsp;&nbsp;- debug:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg: "{{ \_list is search('b\\\\t') }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vars:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\_list: ["a", "b\t"]

Additional escaping is also needed when the items are single-quoted  
and \*regex\* is variable. This time because of '\\' is needed after  
evaluation

&nbsp;&nbsp;&nbsp;&nbsp;- debug:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg: "{{ \_list is search(regex) }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vars:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\_list: ['a', 'b\t']  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;regex: 'b\\\\t'

Finally, one more additional escaping is needed when you put the  
\*regex\* as a value

&nbsp;&nbsp;&nbsp;&nbsp;- debug:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg: "{{ \_list is search('b\\\\\\\\t') }}"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vars:  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\_list: ['a', 'b\t']

All tasks above return True.

---

<div class="post-metadata">

**Author:** ![dnmvisser](https://avatars.discourse-cdn.com/v4/letter/d/8e8cbc/32.png) [@dnmvisser](https://forum.ansible.com/u/dnmvisser)\
**Post date:** [June 21, 2022, 4:40am UTC](https://forum.ansible.com/t/how-can-i-match-s-or-t-in-a-search-test/36755/9 "2022-06-21T04:40:54Z")

</div>

This overview is worthy of its own paragraph in the ansible docs!
