# Regular Expressions
Introduced in Tasks 1.12.0.
[Regular expression](https://en.wikipedia.org/wiki/Regular_expression) ("regex") searches are a powerful alternative to the simple `includes` and `does not include` searches.
### Take Care
> Regular expression (or 'regex') searching is a powerful but advanced feature that requires thorough knowledge in order to use successfully, and not miss intended search results.
It is easy to write a regular expression that looks like it is correct, but which uses a special character that completely changes the meaning of the search string.
For example, `\d` does **not** match the **two** characters `\d`, it matches any **one** of the following characters: `0123456789`.
This documentation gives only a brief overview of the facility, with a few motivating examples, and then links to other resources, for thorough treatment.
Having said that, regex searches are a valuable tool, used in many other tools, and time invested in learning about them can pay off well in future, in many other tools and scenarios.
The components of a regex search filter are:
1. The field name, for example `description` or `path`
2. Either `regex matches` or `regex does not match`
3. The search pattern, inside a pair of forwards slashes, for example `/pc_abigail|pc_edwina|at_work/`
- That pattern searches for `pc_abigail`, `pc_edwina` or `at_work`, without the need to create a boolean combination of three separate filters
- Note that many of the allowed flags are not relevant in the Tasks context, because there are no multi-line searches or global searches, for example.
Case-sensitive example, showing the components:
description regex matches /pc_abigail|pc_edwina|at_work/
^1 ^2 ^3
Case-INsensitive example, showing the components:
description regex matches /pc_abigail|pc_edwina|at_work/i
^1 ^2 ^3 ^4
- Regex searches are **case-sensitive**, unlike the simpler `includes` and `does not include`
- A regex search can be made **insensitive** by appending a `i` flag after the closing `/`, for example: `/I aM cAsE INsensitive because of the LiTle i after the closing slash/i`
- Tasks does not support multi-line regex searches, as each task is a single line.
## Escaping special characters
To search for any of the characters `[ \ ^ $ . | ? * + ( )` literally in Tasks, you should put a `\` character before each of them.
See the next section for the meaning of some of these characters.
> Since Tasks 4.3.0, it is no longer necessary to escape `/` characters as `\/`, although searches will still work if you do escape them.
> So these two searches are now identical, and will both search for tasks in any folder that contains `Root/Sub-Folder/Sub-Sub-Folder` anywhere:
> folder regex matches /Root/Sub-Folder/Sub-Sub-Folder/
> folder regex matches /Root\/Sub-Folder\/Sub-Sub-Folder/
## Explain: inspecting regular expressions
> Introduced in Tasks 4.3.0.
To see how Tasks interpreted your regular expression, you can add an `explain` line to the query.
For example, the results of this query:
<!-- snippet: DocsSamplesForExplain.test.explain_regular_expression.approved.query.text -->
path regex matches /^Root/Sub-Folder/Sample File\.md/i
<!-- endSnippet -->
will have this extra text in an [[Explaining Queries|explanation]] at the start:
<!-- snippet: DocsSamplesForExplain.test.explain_regular_expression.approved.explanation.text -->
Explanation of this Tasks code block query:
path regex matches /^Root/Sub-Folder/Sample File\.md/i =>
using regex: '^Root\/Sub-Folder\/Sample File\.md' with flag 'i'
<!-- endSnippet -->
The use of apostrophes (`'`) rather than forward slashes (`/`) in the explanation is intended to emphasise that the delimiting slashes in the query are not included in the search strings.
## Special characters
If using regex searches, it is important to be aware of the available special characters for several reasons:
1. They enable complex queries to written in simple ways
2. They can cause confusing results or broken searches, if not "escaped" in the search.
- `.` matches any character
- `[...]` means search for any of the characters in the square brackets.
- For example, `[aeiou]` will match any of an `a`, `e`, `i`, `o` or `u`.
- Start and end
- `^` matches the start of the string (but when `[^inside brackets]`, it means "not")
matches the end of the string
- `|` is an `OR` in regular expressions
- `\` adds special meaning to some characters. For example:
- `\d` matches one digit, from 0 to 9
- `\D` matches character that is not a digit
## Important links
- [Regex Tutorial](https://regexone.com/)
- [Regex Cheat Sheet](https://www.rexegg.com/regex-quickstart.html)
Online tools for experimenting with - and testing - regular expressions:
## Known limitations
Please be aware of the following limitations in Tasks' implementation of regular expression searching:
- [Lookahead and Lookbehind](https://www.regular-expressions.info/lookaround.html) searches are untested, and are presumed not to work on Apple mobile devices, or to cause serious performance problems with slow searches.
## Regular expression examples
Below are some example regex searches, to give some ideas of what can be done.
There are some more examples in the [Tasks-Demo sample vault](https://github.com/obsidian-tasks-group/obsidian-tasks/tree/main/resources/sample_vaults/Tasks-Demo), in the file [Regular Expression Searches](https://github.com/obsidian-tasks-group/obsidian-tasks/blob/main/resources/sample_vaults/Tasks-Demo/Filters/Regular%20Expression%20Searches.md).
### Searching the start of a field
Find tasks whose description begins with Log, exact capitalisation:
description regex matches /^Log/
Find tasks whose description begins with Log, ignoring capitalisation
description regex matches /^Log/i
### Finding empty fields
I want to find tasks that have no description, perhaps because they were created from a template:
description regex matches /^$/
I want to exclude tasks with no description:
description regex does not match /^$/
How this works: in regular expressions, `/^$/` matches text where there is nothing between the start and the end.
### Finding tasks that are waiting
I want to find tasks that are waiting for something else. But 'waiting' can be spelled in several different ways:
description regex matches /waiting|waits|wartet/i
### Finding times
Find tasks containing a time in the description - simple version. This matches invalid times, such as `99:99`, as `\d` means 'any digit'.
description regex matches /\d\d:\d\d/
Find tasks containing a time in the description. This is more precise than the previous example, thanks to specifying which digits are allowed in each position.
description regex matches /[0-9]:[0-5][0-9]/
### Finding sub-tags
Suppose you wanted to search for tags of this form: `#tag/subtag3/subsubtag5`, where the `3` and the `5` are allowed to be any single digit.
- We can use either `[0-9]` or `\d` to match a single digit.
- To find a sub-tag, any `/` characters must be 'escaped' to prevent them truncating the rest of the search pattern.
Escaping the `/` leads us to this instruction, which we have made case-insensitive to find capitalised tags too:
tags regex matches /#tag\/subtag[0-9]\/subsubtag[0-9]/i
### Finding short tags
Suppose you wanted to search for tasks with a very short tag in: `#t`, and to not match tags like `#task` and `#t/subtag`.
tag regex matches /#t$/i
prevents there being any more characters in the tag after the search pattern.
The `i` makes the search case-insensitive.