Regexes aren't really all that hard if you avoid all the crazy back reference craziness. I've taught them to non-programmers in about a half-hour and they were able to use them reasonably well right after with a couple reminders.

There's three things you need:

1 - concatenation - basically one thing next to another, 'a' goes next to 'b' to make 'ab' which matches any string with that in it. Examples:

'xzyqr2321abtwe' - matches

'zyxabc' - matches

'abcxyz' - matches

'ab' - matches

'ba' - doesn't match

'azb' - doesn't match

2 - alternation - one thing or another. The operator for this is the pipe symbol '|'. So 'a|b' is 'a or b'.

'xzyqr2321abtwe' - matches

'xzyqr2321atwe' - matches

'xzyqr2321btwe' - matches

'zyxabc' - matches

'abcxyz' - matches

'ab' - matches

'azb' - matches

Here's another 'abc|cab' 'abc or cab'

'xzyqr2321abtwa' - doesn't match

'zyxabc' - matches

'zyxcba' - doesn't match

'zyxcab' - matches

If it helps, you can use parentheses to group blocks of things for clarity.

'(abc)|(cab)'

3 - repetition - the operator we want to care about is '* ' also called the Kleene star. This means that anything that comes before the star can repeat 0 or more times.

so 'a* ' means a pattern of 'a' 0 or more times.

'xzyqr2321abtwe' - matches

'xzyqr2321btwe' - matches (because of zero or more times)

'xzyqr2321btwaaaaaaaaa' - matches

so if you want to match an 'a' one or more times you can simply use rule #1 (concatenation) and put 'aa* '

'xzyqr2321abtwe' - matches

'xzyqr2321btwe' - doesn't match

'xzyqr2321btwaaaaaaaaa' - matches

It turns out this is such a common regex, that some "syntactic sugar" was invented to make it easier to work with, the '+' symbol. Which is used exactly the same way: 'aa* ' = 'a+ '

Congratulations, you now know everything you need to make a regex that can pretty much do anything. So what about all that other line noise one usually sees in a regex? That's more "syntactic sugar", designed to make certain kinds of regexes simpler to write.

For example, a regex using the above rules that can match any alphabet letter from a through f is: a|b|c|d|e|f

This is a lot of typing, so you can use square brackets to build what's called a "character class". '[abcdef]' = 'a|b|c|d|e|f'

If you have a long string of characters, you can use some more sugar and simply put a '-' in between the first and last characters '[a-f]' = '[abcdef]'

Here's a complex example, a regex that can match any lower-case alphabet character or number '[0-9a-z]'

It also turns out that a special character class pattern that can match any character (except for newlines) is so common that a special operator '.' was created. '.' matches literally anything.

For example, concatenating it with an "any number" regex gives you '.[0-9]' which means any character followed by a number.

For repetition, there's also some syntactic sugar, here's a table, these all go after the thing you want repeated:

* - 0 or more times

+ - 1 or more times

{p} - p times

{p,q} - p to q times

{,q} - 0 to q times

{p,} - at least p times

? - 0 or 1 times

Finally, in the list of basic regex stuff, there's "capturing", this is how regexes get used to parse strings. It works basically like this, anything that is matched inside of a parentheses gets "copied" to a special variable. It depends on your language on where this variable is. The name of the variable is typically some 1, indexed variable like $1, $2, $3. The number of the variable is the number of left parentheses in the regex.

Example: 'abc(.+)123'

abcd123 - matches, $1 is 'd'

abcf123 - matches, $1 is 'f'

abcqqq123 - matches, $1 is 'qqq'

abc123 - doesn't match

Another example: (abc([0-9]+))

abc123 - matches $1 is abc123 $2 is 123

If you want to suppress this capturing behavior, the '(' parentheses should be written '(?:'

(?:abc([0-9]+))

Try these out here, it does a nice job highlighting https://regex101.com/ it calls the capture variable "groups" and shows them on the right under "capture information"

There, that's about it. Other advanced techniques like greedy matching, negative character classes, callbacks, etc. flow pretty nicely from these basic ideas.